8

我的OAuth2授权服务器提供用户信息:Spring Security OAuth2 - 如何使用OAuth2Authentication对象?

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; 
    } 
} 

而且我实现了OAuth2用户端作为独立的春天启动应用程序。

@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

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 

用户成功验证:

@Controller 
public class MainController { 

    @RequestMapping(value = "/") 
    public String index(Principal principal) { 
     System.out.println(principal); 
     // or[email protected]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"; 
    } 
} 

但我不知道如何使用提供OAuth2Authentication对象在我的应用程序。它几乎没用。

当我尝试使用任何Thymeleaf安全标签

<span sec:authentication="principal.fullName">Username</span> 
<span sec:authentication="principal.authorities">Authorities</span> 
<span sec:authentication="principal.userAuthentication.details.fullName">Usernames</span> 

..出现以下异常:

Error retrieving value for property "property name here" of authentication object of class org.springframework.security.oauth2.provider.OAuth2Authentication 

标准Spring Security的方法isUserInRole()不是工作压力太大:

System.out.println(servletRequest.isUserInRole("ROLE_SUPERUSER")); 
// false 

我应该实现自定义Thymeleaf安全方言和hasRole()方法d?或者更简单的解决方案存在?

+1

'principal'(如'authentication.getPrincipal()')是通常一个'String'所以我怀疑它有不同的属性。 –

+0

@M。 Deinum感谢您的评论!找到了! Thymeleaf标签不起作用,因为方言操作[security.core.Authentication](https://github.com/spring-projects/spring-security/blob/master/core/src/main/java/org/springframework/security /core/Authentication.java)对象,它不包含'UserAuthentication'字段(这是我的自定义属性存储的地方)。我相信'isUserInRole()'方法不起作用,因为我使用了自定义的'GrantedAuthority'对象。所以我只需要用'User'替换'Principal'并将权限转换为适当的集合。 – Vespin

回答

1

好吧,经过大量的挖掘,我找到了解决方案。

长话短说:ResourceServerTokenServices.loadAuthentication()应该重写方法以从OAuth2资源服务器响应中提取自定义主体和/或权限。主要逻辑封装在extractAuthentication()方法中。

配置

@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; 
    } 
} 

服务

public class CustomUserInfoTokenServices implements ResourceServerTokenServices { 
    // exactly the same as org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices 
    // except extractAuthentication() method 
} 

PS

春季启动版本提供了更灵活的API。请参阅PrincipalExtractor界面。不幸的是它仅在2周前被添加,并且在当前的稳定版1.3.5.RELEASE版本中不被支持。

希望这有助于

+0

你是否在auth服务器上调用/ oauth/check_token? –

相关问题