Spring Security OAuth2 自定义GrantedAuthority授权接口

使用Security OAuth2的时候需要返回给前端用户的角色或者权限,框架提供了GrantedAuthority接口,有一个默认的实现SimpleGrantedAuthority,但是它只能返回简单
的字符串,如果我们想灵活的使用很难控制;所以我这边通过实现GrantedAuthority接口,自定义实现权限控制;

自定义授权接口如下

/**
 * @Description: 自定义GrantedAuthority接口
 * @Package: cn.appblog.security.oauth2.authority.UserGrantedAuthority
 * @Version: 1.0
 */
public class UserGrantedAuthority implements GrantedAuthority {
    private Map<String, Object> authoritys = Maps.newHashMap();

    public UserGrantedAuthority(String name, Object value) {
        authoritys.put(name, value);
    }

    @Override
    public String getAuthority() {
        return JSON.toJSONString(authoritys);
    }
}

用户验证信息类中的使用方法

/**
 * @Description: 用户认证
 * @Package: cn.appblog.security.oauth2.service.UserAuthDetailsService
 * @Version: 1.0
 */
@Component
public class UserAuthDetailsService implements UserDetailsService {
    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * 根据用户名查询用户角色、权限等信息
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        GrantedAuthority authority = new UserGrantedAuthority("username", username);

        JSONArray array = new JSONArray();
        array.add("/a/b");
        array.add("/a/c");
        array.add("/oauth/token");
        GrantedAuthority interfaces = new UserGrantedAuthority("interfaces", array);

        /**
         isEnabled 账户是否启用
         isAccountNonExpired 账户没有过期
         isCredentialsNonExpired 身份认证是否是有效的
         isAccountNonLocked 账户没有被锁定
         */
        return new User(username, passwordEncoder.encode("123456"),
                true,
                true,
                true,
                true,
                Arrays.asList(authority, interfaces));
    }

}

控制器方法获取用户信息解析权限及返回前端

/**
 * /oauth/token(令牌端点)刷新token信息
 */
@RequestMapping(value = "refresh_token", method = RequestMethod.POST)
public ResponseEntity<BaseResponse> refreshToken(@RequestParam String refresh_token) {
    try {
        ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
        resource.setId(propertyService.getProperty("spring.security.oauth.resource.id"));
        resource.setClientId(propertyService.getProperty("spring.security.oauth.resource.client.id"));
        resource.setClientSecret(propertyService.getProperty("spring.security.oauth.resource.client.secret"));
        resource.setGrantType(GrantTypeEnum.REFRESH_TOKEN.getGrant_type());
        resource.setAccessTokenUri(propertyService.getProperty("spring.security.oauth.token.uri"));

        ResourceOwnerPasswordAccessTokenProvider provider = new ResourceOwnerPasswordAccessTokenProvider();
        OAuth2RefreshToken refreshToken = tokenStore.readRefreshToken(refresh_token);
        OAuth2AccessToken accessToken = provider.refreshAccessToken(resource, refreshToken, new DefaultAccessTokenRequest());

        Map<String, Object> result = Maps.newLinkedHashMap();
        result.put("access_token", accessToken.getValue());
        result.put("token_type", accessToken.getTokenType());
        result.put("refresh_token", accessToken.getRefreshToken().getValue());
        result.put("expires_in", accessToken.getExpiresIn());
        result.put("scope", StringUtils.join(accessToken.getScope(), ","));
        result.putAll(accessToken.getAdditionalInformation());

        Collection<? extends GrantedAuthority> authorities = tokenStore.readAuthentication(accessToken).getUserAuthentication().getAuthorities();
        JSONObject jsonObject = new JSONObject();
        for (GrantedAuthority authority : authorities) {
            jsonObject.putAll(JSONObject.parseObject(authority.getAuthority()));
        }
        result.put("authorities", jsonObject);

        return ResponseEntity.ok(BaseResponse.createResponse(HttpStatusMsg.OK, result));
    } catch (Exception e) {
        e.printStackTrace();
        return ResponseEntity.ok(BaseResponse.createResponse(HttpStatusMsg.AUTHENTICATION_EXCEPTION, e.toString()));
    }
}

测试返回结果

{
    "status": 200,
    "message": "SUCCESS",
    "data": {
        "access_token": "ce63485567c648f0b20135ae8027a732",
        "refresh_token": "3598ee77dddb4cf1865d6c1e09b4700b",
        "scope": "all",
        "token_type": "bearer",
        "expires_in": 58,
        "client_id": "client_password",
        "authorities": {
            "interfaces": [
                "/a/b",
                "/a/c",
                "/oauth/token"
            ],
            "username": "admin"
        }
    }
}

本文转载参考 原文 并加以调试

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/03/20/spring-security-oauth2-custom-grantedauthority-authorization-interface/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
Spring Security OAuth2 自定义GrantedAuthority授权接口
使用Security OAuth2的时候需要返回给前端用户的角色或者权限,框架提供了GrantedAuthority接口,有一个默认的实现SimpleGrantedAuthority,但是它只能返回简……
<<上一篇
下一篇>>
文章目录
关闭
目 录