Spring Security OAuth2 自定义GrantedAuthority授权接口

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

自定义授权接口如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* @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);
}
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/**
* @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));
}

}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/**
* /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()));
}
}

测试返回结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"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"
}
}
}

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

Powered by AppBlog.CN     浙ICP备14037229号

Copyright © 2012 - 2020 APP开发技术博客 All Rights Reserved.

访客数 : | 访问量 :