我的安全配置似乎不正确。无论我在使用hasRole时做什么,我的endpoint总是返回403。
此外,除非我在这两个下复制我的antMatchers,否则我无法得到任何东西。requestMatchers()
和。authorizeRequests()
。很明显,我遗漏了一些东西。
基本上,我希望所有内容都需要身份验证,但只有当用户是某些组的成员时(现在只需要admin),少数endpoint才可以访问。
我的安全配置如下。hasRole
旁边的一切都有效。
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.requestMatchers()
.antMatchers(HttpMethod.GET, "/v2/api-docs", "/swagger-resources/**", "/swagger-ui.html")
.antMatchers(HttpMethod.GET, "/users")
.and()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/v2/api-docs", "/swagger-resources/**", "/swagger-ui.html").permitAll()
.antMatchers(HttpMethod.GET, "/users").hasRole("ADMIN")
.anyRequest().authenticated();
}
// Inspiration: https://spring.io/blog/2015/06/08/cors-support-in-spring-framework#comment-2416096114
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**");
}
}
我的AuthenticationConfiguration如下
@Configuration
@EnableResourceServer
public class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {
private final UserDetailsService userService;
private final PasswordEncoder passwordEncoder;
public AuthenticationConfiguration(UserDetailsService userService, PasswordEncoder passwordEncoder) {
this.userService = userService;
this.passwordEncoder = passwordEncoder;
}
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userService)
.passwordEncoder(passwordEncoder);
}
}
我的AuthorizationServerConfiguration如下
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
private final AuthenticationManager authenticationManager;
public AuthorizationServerConfiguration(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("html5")
.secret("password")
.authorizedGrantTypes("password")
.scopes("openid");
}
}
我很乐意发布我的用户服务和其他东西。但除了hasRole
和主体
之外,一切似乎都可以工作,并加载了正确的权限(角色)。但请让我知道我是否应该发布更多代码。
完整的源代码可以在这里找到。
我也有同样的问题,只是忘记了从UserDetails(SpringSecurity类)实现getAuthorities()方法。查看我的实体:
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
@Entity
@Table(name = "tb_user")
public class User implements UserDetails, Serializable {
private static final long serialVersionUID = -6519124777839966091L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
@Column(unique = true)
private String email;
private String password;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "tb_user_role",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private Set<Role> roles = new HashSet<>();
public User() {
}
public User(Long id, String firstName, String lastName, String email, String password) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.password = password;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public void setPassword(String password) {
this.password = password;
}
public Set<Role> getRoles() {
return roles;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return roles.stream().map(role -> new SimpleGrantedAuthority(role.getAuthority()))
.collect(Collectors.toList());
}
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return email;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(id, user.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
默认情况下,getAuthorities方法返回null当您从安全包扩展UserDetails类时,您需要实现如下内容:
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return roles.stream().map(role -> new SimpleGrantedAuthority(role.getAuthority()))
.collect(Collectors.toList());
}
我希望这能帮助到别人,对不起我的英语错误!呵呵
继我对这个问题的评论之后,我将提供用于测试的OAuth2配置类示例。我总是使用两种不同的webapp,因为我想在auth-server和resource-server之间有一条清晰的界限(而且这会使配置变得更加困难……),因此,我的示例在单个webapp中使用时可能需要进行一些调整。
身份验证服务器的配置:
@EnableAuthorizationServer
@Configuration
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
private TokenStore tokenStore;
private DataSource dataSource;
@Autowired
public OAuth2Config(TokenStore tokenStore,
DataSource dataSource) {
this.tokenStore = tokenStore;
this.dataSource = dataSource;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore);
}
@Configuration
public static class TokenStoreConfiguration {
@Bean
public TokenStore tokenStore(DataSource dataSource) {
return new JdbcTokenStore(dataSource);
}
}
}
资源服务器的配置:
@EnableResourceServer
@Configuration
public class OAuth2Config extends ResourceServerConfigurerAdapter {
public static final String PROPERTY_RESOURCE_ID = "com.test.oauth.resourceId";
private Environment environment;
private TokenStore tokenStore;
@Autowired
public OAuth2Config(Environment environment,
TokenStore tokenStore) {
this.environment = environment;
this.tokenStore = tokenStore;
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenStore(tokenStore)
.resourceId(environment.getProperty(PROPERTY_RESOURCE_ID))
.stateless(true);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/demo")
.access("hasRole('DEMO')")
.anyRequest().denyAll()
.and()
.formLogin().disable()
.logout().disable()
.jee().disable()
.x509().disable();
}
@Configuration
public static class TokenStoreConfiguration {
@Bean
public TokenStore tokenStore(DataSource dataSource) {
return new JdbcTokenStore(dataSource);
}
}
}
显然,这需要配置一个数据源bean。此实现使用了spring security OAuth2提供的默认表(它们远非理想的,但可以根据需要进行自定义)。
您可能需要根据您的情况调整一些内容(如果人们可能想将其与JDBC一起使用,我将保留我提供的类作为参考):
编辑:看到ritesh.garg的答案,我认为我提供的可能无法解决您的问题,但可能有助于一些人弄清楚在哪里以及如何开始配置Spring Security OAuth2(当我第一次这样做时,我发现很难做到,因为那时我找不到任何清晰的示例,尽管这可能已经改变了)
你试过用“ROLE_ADMIN”而不仅仅是“ADMIN”吗?看看这个作为参考:
Spring security在所有角色名称中添加了前缀“ROLE\uu”?
我试图根据角色限制对endpoint的访问。我在stackoverflow上搜索了一个解决方案,尝试了一些,但没有成功地解决我的问题。我尝试在全局配置(WebSecurityConfig)和预授权注释中进行限制,调用时都返回403。我的测试用户拥有SYS_ADMIN角色,我已经验证了这个流,它实际上拥有这个角色。以下是我的消息来源。 全球网络安全配置 人员控制员 榜样
问题内容: 我以前使用过媒体播放器,但从未遇到过此问题。每当我尝试使用MediaPlayer.create()时,该方法都会使我为null,并且无法播放声音。有什么我想念的吗? 我的sound.mp3在我的原始文件夹中,通过将声音拖到eclipse中的文件夹中,我将其放置在其中。请帮忙,因为我以前玩过声音,所以这真的困扰我:( 问题答案: 如果create() API由于某种原因失败,则返回nul
问题内容: 尽管是有效的类,但以下代码会打印。 文档说方法返回 由 aClassName 命名的类对象,或者如果当前没有加载该名称的类。如果 aClassName 为,则返回。 我也试图获得当前的viewcontroller已加载但仍然得到 可能是什么问题? 更新: 即使尝试这样做,我仍然可以 问题答案: 该函数 确实 适用于(纯和Objective-C派生的)swift类,但是仅当您使用全限定名
问题内容: 我觉得有点愚蠢,但它不起作用: 我有如果给定的用户是unicode。如果字符串中包含或,我想打印成功,但是我总是得到的结果。 问题答案: 隐式锚定到字符串的开头。如果要在字符串中搜索可以在字符串中任何位置的子字符串,则需要使用: 输出: 另外,Python Regexes不需要在开头和结尾都有一个。 最后,我添加到该行的末尾,因为我认为这就是您想要的。否则,您会得到类似的信息,但并不太
我正在尝试使用NSKeyDarchiver在应用程序关闭和运行周期之间存储数据。我试图存储的根对象是一个NSMutableArray,但在这个对象中有基础对象和自定义对象的集合(所有这些都符合NSCoding)。 文件保存代码如下 该文件保存fine并且不会抛出异常。再次启动应用程序时,使用以下代码恢复该文件。 在这一点上,sessionData总是为零,而pData是几千字节长的,因此我知道问题
我有以下异常处理程序: 此代码应该包装异常并返回具有正确状态代码的ResponseEntity。