千家信息网

Spring Security OAuth2 token权限隔离的示例分析

发表于:2024-12-12 作者:千家信息网编辑
千家信息网最后更新 2024年12月12日,这篇文章将为大家详细讲解有关Spring Security OAuth2 token权限隔离的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、哪里重写?资
千家信息网最后更新 2024年12月12日Spring Security OAuth2 token权限隔离的示例分析

这篇文章将为大家详细讲解有关Spring Security OAuth2 token权限隔离的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

一、哪里重写?

资源服务器向授权服务服务器获取资源时候,返回的user信息重写,加入authorities

@RestController@Slf4jpublic 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 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权限隔离的示例分析"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

0