我尝试使用OAuth2创建Spring Boot App。我创建了User类,定义如下:
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@NotNull
private String username;
@NotNull
private String password;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Role> roles;
我创建了用户&#34; test&#34;有两个角色:&#34; USER&#34;和&#34; ADMIN&#34;,但当我想发送POST请求到&#34; / get&#34;处理程序我获得401状态。 我的ResourceServerConfig:
@Autowired
private TokenStore tokenStore;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("resource").tokenStore(tokenStore);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/msg/**").authenticated()
.antMatchers("/get/**").hasRole("ADMIN");
}
AuthorizationServerConfig @Autowired private AuthenticationManager authenticationManager;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("trustedClient")
.authorizedGrantTypes("client_credentials","password")
.authorities("ROLE_CLIENT","ROLE_TRUSTED_CLIENT")
.scopes("read","write","trust")
.accessTokenValiditySeconds(5000)
.secret("secret");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.pathMapping("/oauth/token", "/login")
.tokenEnhancer(tokenEnhancer())
.tokenStore(tokenStore())
.authenticationManager(authenticationManager);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.checkTokenAccess("isAuthenticated()");
}
@Bean
public TokenEnhancer tokenEnhancer(){
return new CustomTokenEnhancer();
}
@Bean
public TokenStore tokenStore(){
return new InMemoryTokenStore();
}
CustomTokenEnhancer
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();
User user = new User();
user.setUsername(userDetails.getUsername());
user.setPassword(userDetails.getPassword());
List<Role> roles = new ArrayList<>();
for(GrantedAuthority role: userDetails.getAuthorities())
roles.add(new Role(role.getAuthority()));
user.setRoles(roles);
Map<String, Object> additional = new HashMap<>();
additional.put("user", user);
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additional);
return accessToken;
}
和最后一个CustomUserDetails
public CustomUserDetails(User byUsername){
this.username = byUsername.getUsername();
this.password = byUsername.getPassword();
List<GrantedAuthority> auths = new ArrayList<>();
for(Role role: byUsername.getRoles())
auths.add(new SimpleGrantedAuthority(role.getName().toUpperCase()));
this.authorities = auths;
System.out.println(this.authorities);
}
这最后一个println返回[USER,ADMIN]。
答案 0 :(得分:0)
如果您的配置正确,那么默认情况下,用户角色应该具有&#39; ROLE _&#39;字首。只需将此前缀添加到用户&#39;角色和所有都应该有用。
如果在此更改后您仍然收到401状态,请尝试覆盖application.properties(application.yml)中的oauth过滤器顺序:
security:
oauth2:
resource:
filter-order: 3
此问题与1.5版本以来spring oauth的最新变化有关。请查看此链接https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.5-Release-Notes#oauth-2-resource-filter。
答案 1 :(得分:0)
更改此部分:
import sys
import re
import itertools
import builtins
from builtins import __build_class__
def build_class(func, name, *bases, metaclass=None, **kwds):
if bases[-1] is object:
bases = bases[:-1]
bases += HackishClass, object
if metaclass is None:
return __build_class__(func, name, *bases, **kwds)
return __build_class__(func, name, *bases, metaclass=metaclass, **kwds)
private_regex = re.compile('_(?P<class>.*?)__(?P<name>.*)')
class HackishClass:
__slots__ = ()
def __getattribute__(self, key):
match = private_regex.match(key)
if match is not None:
for depth in itertools.count(1):
frame = sys._getframe(depth)
if ...: # snip
# Check for the original attribute access here.
break
class_name = ... # HERE! MAGIC GOES HERE!
if class_name != match['class']:
raise AttributeError("This is private! Keep out.")
return super().__getattribute__(key)
builtins.__build_class__ = build_class
收件人:
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/msg/**").authenticated()
.antMatchers("/get/**").hasRole("ADMIN");
}