8

私は、ユーザーの情報を提供してのOAuth2認証サーバーを持っている:Springセキュリティ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クライアントを実装しました。

@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オブジェクトを使用する方法を理解することはできません。

@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 

ユーザーが正常に認証します。それはほとんど役に立たない。

私はどんな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 

標準春のセキュリティ方法isUserInRole()があまり機能していない:

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

カスタムThymeleafセキュリティダイアレクトとhasRole()メソッドを実装する必要がありますかd?あるいはもっと簡単な解決法が存在するでしょうか?

+1

' principal'に役立ちます。 –

+0

@M。 Deinumあなたのコメントありがとう!それを見つけた! Thymeleafタグは、dialectが動作するため動作しません[security.core.Authentication](https://github.com/spring-projects/spring-security/blob/master/core/src/main/java/org/springframework/security /core/Authentication.java) 'UserAuthentication'フィールド(私のカスタムプロパティが格納されているフィールド)を持たないオブジェクトです。カスタム 'GrantedAuthority'オブジェクトを使用したため、' isUserInRole() 'メソッドが動作しないと思います。だから、私は 'Principal'を' User'に置き換え、権限を適切なコレクションに変換する必要があります。 – Vespin

答えて

1

[OK]を、私は解決策を見つけた多くの掘削の後。

短いストーリー: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バージョン。

希望これはので、私はそれは異なる特性を持っている疑い一般 `STRING`である(()` `authentication.getPrincipalのように)

+0

認証サーバーで/ oauth/check_tokenを呼び出していますか? –

関連する問題