spring security oauth2 github 用户权限(OAuth2UserService)


spring security oauth2 github 用户权限(OAuth2UserService)

 

应用:使用自定义的OAuth2UserService设置用户权限

 

 

**********************

相关类及接口

 

OAuth2UserService

@FunctionalInterface
public interface OAuth2UserService<R extends OAuth2UserRequest, U extends OAuth2User> {
    U loadUser(R var1) throws OAuth2AuthenticationException;
}

 

DefaultOAuth2UserService

public class DefaultOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
    private static final String MISSING_USER_INFO_URI_ERROR_CODE = "missing_user_info_uri";
    private static final String MISSING_USER_NAME_ATTRIBUTE_ERROR_CODE = "missing_user_name_attribute";
    private static final String INVALID_USER_INFO_RESPONSE_ERROR_CODE = "invalid_user_info_response";
    private static final ParameterizedTypeReference<Map<String, Object>> PARAMETERIZED_RESPONSE_TYPE = new ParameterizedTypeReference<Map<String, Object>>() {
    };
    private Converter<OAuth2UserRequest, RequestEntity<?>> requestEntityConverter = new OAuth2UserRequestEntityConverter();
    private RestOperations restOperations;

    public DefaultOAuth2UserService() {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler());
        this.restOperations = restTemplate;
    }

    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
        Assert.notNull(userRequest, "userRequest cannot be null");
        if (!StringUtils.hasText(userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri())) {
            OAuth2Error oauth2Error = new OAuth2Error("missing_user_info_uri", "Missing required UserInfo Uri in UserInfoEndpoint for Client Registration: " + userRequest.getClientRegistration().getRegistrationId(), (String)null);
            throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
        } else {
            String userNameAttributeName = userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName();
            if (!StringUtils.hasText(userNameAttributeName)) {
                OAuth2Error oauth2Error = new OAuth2Error("missing_user_name_attribute", "Missing required \"user name\" attribute name in UserInfoEndpoint for Client Registration: " + userRequest.getClientRegistration().getRegistrationId(), (String)null);
                throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
            } else {
                RequestEntity request = (RequestEntity)this.requestEntityConverter.convert(userRequest);

                ResponseEntity response;
                OAuth2Error oauth2Error;
                try {
                    response = this.restOperations.exchange(request, PARAMETERIZED_RESPONSE_TYPE);
                } catch (OAuth2AuthorizationException var10) {
                    oauth2Error = var10.getError();
                    StringBuilder errorDetails = new StringBuilder();
                    errorDetails.append("Error details: [");
                    errorDetails.append("UserInfo Uri: ").append(userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri());
                    errorDetails.append(", Error Code: ").append(oauth2Error.getErrorCode());
                    if (oauth2Error.getDescription() != null) {
                        errorDetails.append(", Error Description: ").append(oauth2Error.getDescription());
                    }

                    errorDetails.append("]");
                    oauth2Error = new OAuth2Error("invalid_user_info_response", "An error occurred while attempting to retrieve the UserInfo Resource: " + errorDetails.toString(), (String)null);
                    throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString(), var10);
                } catch (RestClientException var11) {
                    oauth2Error = new OAuth2Error("invalid_user_info_response", "An error occurred while attempting to retrieve the UserInfo Resource: " + var11.getMessage(), (String)null);
                    throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString(), var11);
                }

                Map<String, Object> userAttributes = (Map)response.getBody();
                Set<GrantedAuthority> authorities = new LinkedHashSet();
                authorities.add(new OAuth2UserAuthority(userAttributes));
                OAuth2AccessToken token = userRequest.getAccessToken();
                Iterator var8 = token.getScopes().iterator();

                while(var8.hasNext()) {
                    String authority = (String)var8.next();
                    authorities.add(new SimpleGrantedAuthority("SCOPE_" + authority));
                }

                return new DefaultOAuth2User(authorities, userAttributes, userNameAttributeName);
            }
        }
    }

    public final void setRequestEntityConverter(Converter<OAuth2UserRequest, RequestEntity<?>> requestEntityConverter) {
        Assert.notNull(requestEntityConverter, "requestEntityConverter cannot be null");
        this.requestEntityConverter = requestEntityConverter;
    }

    public final void setRestOperations(RestOperations restOperations) {
        Assert.notNull(restOperations, "restOperations cannot be null");
        this.restOperations = restOperations;
    }
}

 

 

OAuth2User

public interface OAuth2User extends OAuth2AuthenticatedPrincipal {
}

 

DefaultOAuth2User

public class DefaultOAuth2User implements OAuth2User, Serializable {
    private static final long serialVersionUID = 520L;
    private final Set<GrantedAuthority> authorities;
    private final Map<String, Object> attributes;
    private final String nameAttributeKey;

    public DefaultOAuth2User(Collection<? extends GrantedAuthority> authorities, Map<String, Object> attributes, String nameAttributeKey) {
        Assert.notEmpty(authorities, "authorities cannot be empty");
        Assert.notEmpty(attributes, "attributes cannot be empty");
        Assert.hasText(nameAttributeKey, "nameAttributeKey cannot be empty");
        if (!attributes.containsKey(nameAttributeKey)) {
            throw new IllegalArgumentException("Missing attribute '" + nameAttributeKey + "' in attributes");
        } else {
            this.authorities = Collections.unmodifiableSet(new LinkedHashSet(this.sortAuthorities(authorities)));
            this.attributes = Collections.unmodifiableMap(new LinkedHashMap(attributes));
            this.nameAttributeKey = nameAttributeKey;
        }
    }

    public String getName() {
        return this.getAttribute(this.nameAttributeKey).toString();
    }

    public Collection<? extends GrantedAuthority> getAuthorities() {
    public Map<String, Object> getAttributes() {
    private Set<GrantedAuthority> sortAuthorities(Collection<? extends GrantedAuthority> authorities) {

    public boolean equals(Object obj) {
    public int hashCode() {
    public String toString() {

 

OAuth2AuthenticatedPricipal

public interface OAuth2AuthenticatedPrincipal extends AuthenticatedPrincipal {
    @Nullable
    default <A> A getAttribute(String name) {
        return this.getAttributes().get(name);
    }

    Map<String, Object> getAttributes();

    Collection<? extends GrantedAuthority> getAuthorities();
}

 

AuthenticatedPricipal

public interface AuthenticatedPrincipal {
    String getName();
}

 

 

**********************

示例

 

***********************

自定义UserService

 

WebSecurityConfig

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    private UserService userService;

    @Bean
    public PasswordEncoder initPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin().loginPage("/login/github").loginProcessingUrl("/login/form")
                .and()
                .authorizeRequests()
                .antMatchers("/hello").hasAnyAuthority("ROLE_USER")
                .antMatchers("/**").permitAll()
                .and()
                .logout().deleteCookies("JSESSIONID")
                .logoutSuccessUrl("/").permitAll();

        http.oauth2Login().loginPage("/login/github")
                .userInfoEndpoint().userService(this.initOAuth2UserService());
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(initPasswordEncoder());
    }

    private OAuth2UserService<OAuth2UserRequest, OAuth2User> initOAuth2UserService(){
        OAuth2UserService<OAuth2UserRequest,OAuth2User> oAuth2UserService=new DefaultOAuth2UserService();

        return oAuth2UserRequest -> {
            OAuth2User oAuth2User=oAuth2UserService.loadUser(oAuth2UserRequest);

            Map<String,Object> attributes=oAuth2User.getAttributes();
            String attributeNameKey=oAuth2UserRequest.getClientRegistration()
                    .getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName();

            Set<GrantedAuthority> authorities=new HashSet<>();

            authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
            authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));

            return new DefaultOAuth2User(authorities,attributes,attributeNameKey);
        };
    }
}

 

通过认证后控制台输出

org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken@f2e7c93c: 
Principal: Name: [41827785], Granted Authorities: [[ROLE_ADMIN, ROLE_USER]], User Attributes: [{login=lihu12344, id=41827785, node_id=MDQ6VXNlcjQxODI3Nzg1, avatar_url=https://avatars3.githubusercontent.com/u/41827785?v=4, gravatar_id=, url=https://api.github.com/users/lihu12344, html_url=https://github.com/lihu12344, followers_url=https://api.github.com/users/lihu12344/followers, following_url=https://api.github.com/users/lihu12344/following{/other_user}, gists_url=https://api.github.com/users/lihu12344/gists{/gist_id}, starred_url=https://api.github.com/users/lihu12344/starred{/owner}{/repo}, subscriptions_url=https://api.github.com/users/lihu12344/subscriptions, organizations_url=https://api.github.com/users/lihu12344/orgs, repos_url=https://api.github.com/users/lihu12344/repos, events_url=https://api.github.com/users/lihu12344/events{/privacy}, received_events_url=https://api.github.com/users/lihu12344/received_events, type=User, site_admin=false, name=null, company=null, blog=, location=null, email=null, hireable=null, bio=null, public_repos=84, public_gists=0, followers=0, following=0, created_at=2018-07-28T11:56:10Z, updated_at=2020-05-15T03:36:41Z, private_gists=0, total_private_repos=0, owned_private_repos=0, disk_usage=4355, collaborators=0, two_factor_authentication=false, plan={name=free, space=976562499, collaborators=0, private_repos=10000}}]; 
Credentials: [PROTECTED]; 
Authenticated: true; 
Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffff4c9c: RemoteIpAddress: 0:0:0:0:0:0:0:1; 
SessionId: D285092FC82C5F852A3926C82CC91976; 
Granted Authorities: ROLE_ADMIN, ROLE_USER

 用户权限设置为ROLE_ADMIN、ROLE_USER

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值