扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
这篇文章将为大家详细讲解有关Spring Security OAuth2 token权限隔离的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
成都创新互联服务项目包括李沧网站建设、李沧网站制作、李沧网页制作以及李沧网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,李沧网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到李沧省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
一、哪里重写?
资源服务器向授权服务服务器获取资源时候,返回的user信息重写,加入authorities
@RestController @Slf4j public class UserController { @Autowired HttpServletRequest request; @GetMapping("/user") public Principal user(Principal principal) { log.info("获取user信息:{}", JSON.toJSON(principal)); return principal; }
返回的具体用户信息:
{ "principal": { "password": "$2a$10$OjTFAZEzS6qypY4nRZtnM.MzS6F3XsIlkAO/kIFCu30kAk8Yasowa", "phone": "13918438965", "credentialsNonExpired": true, "accountNonExpired": true, "enabled": true, "accountNonLocked": true, "username": "4738195728608789333" }, "authenticated": true, "oAuth3Request": { "redirectUri": "http://www.baidu.com", "responseTypes": ["code"], "approved": true, "extensions": {}, "clientId": "external", "scope": ["auth_base"], "requestParameters": { "code": "ovzMSk", "grant_type": "authorization_code", "scope": "auth_base", "response_type": "code", "redirect_uri": "http://www.baidu.com", "state": "123", "client_secret": "D524C1A0811DA49592F841085CC0063EB62B3001252A9454", "client_id": "external" }, "refresh": false, "grantType": "authorization_code", "authorities": [{ "authority": "auth_base" }], "resourceIds": [] }, "clientOnly": false, "credentials": "", "name": "4738195728608789333", "userAuthentication": { "principal": { "password": "$2a$10$OjTFAZEzS6qypY4nRZtnM.MzS6F3XsIlkAO/kIFCu30kAk8Yasowa", "phone": "13918438965", "credentialsNonExpired": true, "accountNonExpired": true, "enabled": true, "accountNonLocked": true, "username": "4738195728608789333" }, "authenticated": true, "oAuth3Request": { "responseTypes": [], "approved": true, "extensions": {}, "clientId": "gt", "scope": ["frontend"], "requestParameters": { "auth_type": "sms", "device_id": "5c5d1d7b-50ae-4347-9aee-7a7686055f4d", "grant_type": "password", "client_id": "gt", "username": "13918438965" }, "refresh": false, "grantType": "password", "authorities": [{ "authority": "client" }], "resourceIds": [] }, "clientOnly": false, "credentials": "", "name": "4738195728608789333", "userAuthentication": { "principal": { "password": "$2a$10$OjTFAZEzS6qypY4nRZtnM.MzS6F3XsIlkAO/kIFCu30kAk8Yasowa", "phone": "13918438965", "credentialsNonExpired": true, "accountNonExpired": true, "enabled": true, "accountNonLocked": true, "username": "4738195728608789333" }, "authenticated": true, "name": "4738195728608789333", "details": { "auth_type": "sms", "device_id": "5c5d1d7b-50ae-4347-9aee-7a7686055f4d", "grant_type": "password", "client_secret": "D524C1A0811DA49592F841085CC0063EB62B3001252A94542795D1CA9824A941", "client_id": "gt", "username": "13918438965" }, "authorities": [] }, "details": { "tokenType": "Bearer", "tokenValue": "f7870e71-7b0f-4a4a-9c6f-bb6d1f903ad9", "remoteAddress": "0:0:0:0:0:0:0:1" }, "authorities": [] }, "details": { "tokenType": "Bearer", "tokenValue": "7829005c-5ebe-4428-b951-89477b24316e", "remoteAddress": "0:0:0:0:0:0:0:1" }, "authorities": [] }
二、如何重写?
principal是OAuth3Authentication实例,OAuth3Authentication主要包括OAuth3Request storedRequest、Authentication userAuthentication,
重写目的是将storedRequest authorities复制到authoritie中,但问题是authoritie不让修改的,没办法只能重写这个OAuth3Authentication了。
为了改变authoritie重写:
@GetMapping("/user") public Principal user(Principal principal) { log.info("获取user信息:{}", JSON.toJSON(principal)); OAuth3Authentication oAuth3Authentication = (OAuth3Authentication) principal; OAuth3Request storedRequest = oAuth3Authentication.getOAuth3Request(); Authentication userAuthentication = oAuth3Authentication.getUserAuthentication(); // 为了服务端进行token权限隔离 定制OAuth3Authentication CustomOAuth3Authentication customOAuth3Authentication = new CustomOAuth3Authentication(storedRequest, userAuthentication, storedRequest.getAuthorities()); customOAuth3Authentication.setDetails(oAuth3Authentication.getDetails()); log.info("返回用户信息:{}", JSON.toJSON(customOAuth3Authentication)); return customOAuth3Authentication; }
CustomOAuth3Authentication :
package com.brightcns.wuxi.citizencard.auth.domain; import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.CredentialsContainer; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.oauth3.provider.OAuth3Request; import java.util.Collection; /** * @author maxianming * @date 2018/10/29 13:53 */ public class CustomOAuth3Authentication extends AbstractAuthenticationToken { private static final long serialVersionUID = -4809832298438307309L; private final OAuth3Request storedRequest; private final Authentication userAuthentication; /** * Construct an OAuth 2 authentication. Since some grant types don't require user authentication, the user * authentication may be null. * @param storedRequest The authorization request (must not be null). * @param userAuthentication The user authentication (possibly null). */ public CustomOAuth3Authentication(OAuth3Request storedRequest, Authentication userAuthentication, Collection extends GrantedAuthority> authorities) { /** * 为了服务端进行token权限隔离 {@link @PreAuthorize("hasAuthority('server')")},自定义OAuth3Authentication使得支持改变authorities */ super(authorities != null ? authorities : userAuthentication == null ? storedRequest.getAuthorities() : userAuthentication.getAuthorities()); this.storedRequest = storedRequest; this.userAuthentication = userAuthentication; } public Object getCredentials() { return ""; } public Object getPrincipal() { return this.userAuthentication == null ? this.storedRequest.getClientId() : this.userAuthentication .getPrincipal(); } /** * Convenience method to check if there is a user associated with this token, or just a client application. * * @return true if this token represents a client app not acting on behalf of a user */ public boolean isClientOnly() { return userAuthentication == null; } /** * The authorization request containing details of the client application. * * @return The client authentication. */ public OAuth3Request getOAuth3Request() { return storedRequest; } /** * The user authentication. * * @return The user authentication. */ public Authentication getUserAuthentication() { return userAuthentication; } @Override public boolean isAuthenticated() { return this.storedRequest.isApproved() && (this.userAuthentication == null || this.userAuthentication.isAuthenticated()); } @Override public void eraseCredentials() { super.eraseCredentials(); if (this.userAuthentication != null && CredentialsContainer.class.isAssignableFrom(this.userAuthentication.getClass())) { CredentialsContainer.class.cast(this.userAuthentication).eraseCredentials(); } } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof CustomOAuth3Authentication)) { return false; } if (!super.equals(o)) { return false; } CustomOAuth3Authentication that = (CustomOAuth3Authentication) o; if (!storedRequest.equals(that.storedRequest)) { return false; } if (userAuthentication != null ? !userAuthentication.equals(that.userAuthentication) : that.userAuthentication != null) { return false; } if (getDetails() != null ? !getDetails().equals(that.getDetails()) : that.getDetails() != null) { // return false; } return true; } @Override public int hashCode() { int result = super.hashCode(); result = 31 * result + storedRequest.hashCode(); result = 31 * result + (userAuthentication != null ? userAuthentication.hashCode() : 0); return result; } }
主要在OAuth3Authentication基础上修改了30-35行代码
关于“Spring Security OAuth2 token权限隔离的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流