java Spring Security OAuth2 - 如何使用 OAuth2Authentication 对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37544406/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Security OAuth2 - How to use OAuth2Authentication object?
提问by Vespin
I have OAuth2 authorization server which provides user information:
我有提供用户信息的 OAuth2 授权服务器:
public class User implements Serializable, UserDetails {
private Long userID;
private String username;
private String password;
private String fullName;
private String email;
private String avatar;
private boolean enabled;
// etc
}
@RestController
@RequestMapping("/api")
public class APIController {
@RequestMapping("/me")
public User me(@AuthenticationPrincipal User activeUser) {
return activeUser;
}
}
Also I've implemented OAuth2 client as separate Spring Boot application.
此外,我已将 OAuth2 客户端实现为单独的 Spring Boot 应用程序。
@Configuration
@EnableOAuth2Sso
public class OAuth2ClientConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.logout()
.and()
.antMatcher("/**").authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated();
}
}
application.yml
应用程序.yml
security:
user:
password: none
oauth2:
client:
clientId: acme
clientSecret: acmepassword
accessTokenUri: http://localhost:9080/sso/oauth/token
userAuthorizationUri: http://localhost:9080/sso/oauth/authorize
resource:
userInfoUri: http://localhost:9080/sso/api/me
User authenticates successfully:
用户认证成功:
@Controller
public class MainController {
@RequestMapping(value = "/")
public String index(Principal principal) {
System.out.println(principal);
// org.springframework.security.oauth2.provider.OAuth2Authentication@c2e723e8: Principal: superadmin; Credentials: [PROTECTED]; Authenticated: true; Details: remoteAddress=<ADDRESS>, sessionId=<SESSION>, tokenType=bearertokenValue=<TOKEN>; Granted Authorities: {userRoleID=1, authority=ROLE_SUPERUSER}
OAuth2Authentication auth = (OAuth2Authentication) principal;
System.out.println(auth.getUserAuthentication().getDetails());
// {userID=1, username=superadmin, password=***, fullName=SuperUser, [email protected], avatar=null, enabled=true ...
return "index";
}
}
But I can't understand how to use provided OAuth2Authentication object in my application. It almost useless.
但我无法理解如何在我的应用程序中使用提供的 OAuth2Authentication 对象。它几乎没用。
When I'm trying to use any Thymeleaf security tag
当我尝试使用任何 Thymeleaf 安全标签时
<span sec:authentication="principal.fullName">Username</span>
<span sec:authentication="principal.authorities">Authorities</span>
<span sec:authentication="principal.userAuthentication.details.fullName">Usernames</span>
.. the following exception occurs:
.. 发生以下异常:
Error retrieving value for property "property name here" of authentication object of class org.springframework.security.oauth2.provider.OAuth2Authentication
Standard Spring Security methods isUserInRole()
not working too:
标准 Spring Security 方法isUserInRole()
也不起作用:
System.out.println(servletRequest.isUserInRole("ROLE_SUPERUSER"));
// false
Should I implement custom Thymeleaf security dialect and hasRole() method? Or maybe simpler solution exists?
我应该实现自定义 Thymeleaf 安全方言和 hasRole() 方法吗?或者也许存在更简单的解决方案?
回答by Vespin
Ok, after a lot of digging i've found solution.
好的,经过大量挖掘,我找到了解决方案。
Long story short: ResourceServerTokenServices.loadAuthentication()
method should be overriden to extract custom principal and / or authorities from OAuth2 resource server response. Main logic encapsulated in extractAuthentication()
method.
长话短说:ResourceServerTokenServices.loadAuthentication()
应该重写方法以从 OAuth2 资源服务器响应中提取自定义主体和/或权限。封装在extractAuthentication()
方法中的主要逻辑。
Config
配置
@Configuration
@EnableOAuth2Sso
public class OAuth2ClientConfig extends WebSecurityConfigurerAdapter {
@Autowired
private ResourceServerProperties sso;
@Autowired
private OAuth2RestOperations restTemplate;
@Override
public void configure(HttpSecurity http) throws Exception {
http.logout().and().antMatcher("/**").authorizeRequests().antMatchers("/login").permitAll().anyRequest()
.authenticated();
}
@Bean
// very important notice: method name should be exactly "userInfoTokenServices"
public ResourceServerTokenServices userInfoTokenServices() {
CustomUserInfoTokenServices serv = new CustomUserInfoTokenServices(sso.getUserInfoUri(), sso.getClientId());
serv.setTokenType(sso.getTokenType());
serv.setRestTemplate(restTemplate);
return serv;
}
}
Service
服务
public class CustomUserInfoTokenServices implements ResourceServerTokenServices {
// exactly the same as org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices
// except extractAuthentication() method
}
PS:
附注:
New Spring Bootversion provides more flexible API. See PrincipalExtractor
interface. Unfortunately it was added only 2 weeks ago and doesn't supported in current stable 1.3.5.RELEASEversion.
新的Spring Boot版本提供了更灵活的 API。见PrincipalExtractor
界面。不幸的是,它仅在 2 周前添加,当前稳定的1.3.5.RELEASE版本不支持。
Hope this helps
希望这可以帮助