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? –

相關問題