最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

springsecurity第三方授權(quán)認(rèn)證的項(xiàng)目實(shí)踐

 更新時(shí)間:2023年08月15日 09:32:45   作者:愛發(fā)博客的嗯哼  
Spring security 是一個(gè)強(qiáng)大的和高度可定制的身份驗(yàn)證和訪問控制框架,本文主要介紹了springsecurity第三方授權(quán)認(rèn)證的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣可以了解一下

由于博主在做一個(gè)校園項(xiàng)目的時(shí)候使用啦spring security安全框架,然后在整合第三方授權(quán)登錄的時(shí)候,被困擾了好幾天,就想著發(fā)一下這個(gè)文章,希望能給大家?guī)韼椭?/p>

第三方授權(quán)登錄的原理,我就不在這里過多闡述了(作者也是小白,怕給你們帶入歧途),大家不熟悉或者不了解的可以取嗶哩嗶哩看一下不良人的springsecurity教程,后面的課程就是講述的第三方授權(quán)登錄的知識(shí)。也可以看一下《深入淺出spring security》這本書。

單純的springboot項(xiàng)目的話可以直接使用justauth這個(gè)第三方框架,集成啦許多的第三方登錄的接口,只用自己調(diào)用一下api就能解決第三方授權(quán)登錄的問題。

問題描述

現(xiàn)在大多數(shù)軟件和web網(wǎng)站都會(huì)加入第三方授權(quán)登錄的功能,以方便提高用戶的體驗(yàn)。此時(shí)就給我們后端開發(fā)的人帶來了極大的煩惱。

由于此項(xiàng)目加入了springsecurity框架,此時(shí)就不能使用justauth這個(gè)框架了,這個(gè)框架關(guān)于springsecurity的解決還沒完善。所以就要使用springsecurity自帶的oauth2認(rèn)證過濾器(其實(shí)你會(huì)發(fā)現(xiàn)非常簡單就能解決了)。

詳細(xì)步驟(以gitee舉例)

1. 進(jìn)入官網(wǎng)點(diǎn)擊設(shè)置

2. 向下翻轉(zhuǎn),點(diǎn)擊第三方應(yīng)用

3. 點(diǎn)擊創(chuàng)建應(yīng)用后就進(jìn)入下面這個(gè)界面

4. 然后把標(biāo)星的給填上

注意回調(diào)地址格式不要寫錯(cuò),否則springsecurity識(shí)別不出http://IP地址:端口號(hào)/login/oauth2/code/應(yīng)用名稱

5. 在springboot里加入配置

security:
    oauth2:
      client:
        registration:
          gitee:
            client-id: #授權(quán)id
            client-secret:  #授權(quán)密鑰
            authorization-grant-type: authorization_code
            redirect-uri:  #回調(diào)地址
            client-name: gitee #應(yīng)用名稱
            scope: user_info
        provider:
          gitee:
            authorization-uri: https://gitee.com/oauth/authorize
            token-uri: https://gitee.com/oauth/token
            user-info-uri: https://gitee.com/api/v5/user
            user-name-attribute: gitee

6. 此時(shí)要?jiǎng)?chuàng)建一個(gè)實(shí)體類,這個(gè)實(shí)體類是接收第三方應(yīng)用傳輸?shù)氖跈?quán)信息的。每個(gè)應(yīng)用的授權(quán)信息都不同,大家可以在網(wǎng)上單獨(dú)看一下對(duì)應(yīng)的官網(wǎng)都會(huì)返回什么授權(quán)信息。

@NoArgsConstructor
@AllArgsConstructor
@Data
public class OAuth2UserDTO implements OAuth2User {
     private String source;
     private String id;
     private String name;
     private String email;
     private String avatar;
     @JsonIgnore
     @JSONField(serialize = false)
     private List<GrantedAuthority> authorities= AuthorityUtils.createAuthorityList("ROLE_USER");
     @JsonIgnore
     @JSONField(serialize = false)
     private Map<String,Object> attributes;
     @Override
     public Map<String, Object> getAttributes() {
          if (attributes==null){
               attributes=new HashMap<>();
               attributes.put("id",this.getId());
               attributes.put("name",this.getName());
               attributes.put("email",this.getEmail());
          }
          return attributes;
     }
     @Override
     public Collection<? extends GrantedAuthority> getAuthorities() {
          return this.authorities;
     }
     public OAuth2UserDTO(Map<String,Object> attributes,String source){
          this.attributes = attributes;
          this.source = source;
          this.id = attributes.get("id").toString();
          this.name = attributes.get("name").toString();
          this.email = attributes.get("email")==null?null:attributes.get("email").toString();
          this.avatar = attributes.get("avatar_url")==null?null:attributes.get("avatar_url").toString();
     }
}

7. 重寫oauth2認(rèn)證方法

@Service
public class CustomOAuth2UserService implements OAuth2UserService {
    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 CustomOAuth2UserService() {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler());
        this.restOperations = restTemplate;
    }
    @Override
    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_ERROR_CODE,
                    "Missing required UserInfo Uri in UserInfoEndpoint for Client Registration: "
                            + userRequest.getClientRegistration().getRegistrationId(),
                    null);
            throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
        }
        String userNameAttributeName = userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint()
                .getUserNameAttributeName();
        if (!StringUtils.hasText(userNameAttributeName)) {
            OAuth2Error oauth2Error = new OAuth2Error(MISSING_USER_NAME_ATTRIBUTE_ERROR_CODE,
                    "Missing required \"user name\" attribute name in UserInfoEndpoint for Client Registration: "
                            + userRequest.getClientRegistration().getRegistrationId(),
                    null);
            throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
        }
        RequestEntity<?> request = this.requestEntityConverter.convert(userRequest);
        ResponseEntity<Map<String, Object>> response = getResponse(userRequest, request);
        Map<String, Object> userAttributes = response.getBody();
        Set<GrantedAuthority> authorities = new LinkedHashSet<>();
        authorities.add(new OAuth2UserAuthority(userAttributes));
        OAuth2AccessToken token = userRequest.getAccessToken();
        for (String authority : token.getScopes()) {
            authorities.add(new SimpleGrantedAuthority("SCOPE_" + authority));
        }
        //更換為自定義的OAuth2User實(shí)現(xiàn)
        return new OAuth2UserDTO(userAttributes, userNameAttributeName);
    }
    private ResponseEntity<Map<String, Object>> getResponse(OAuth2UserRequest userRequest, RequestEntity<?> request) {
        OAuth2Error oauth2Error;
        try {
            return this.restOperations.exchange(request, PARAMETERIZED_RESPONSE_TYPE);
        } catch (OAuth2AuthorizationException var6) {
            oauth2Error = var6.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(), var6);
        } catch (UnknownContentTypeException var7) {
            String errorMessage = "An error occurred while attempting to retrieve the UserInfo Resource from '" + userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri() + "': response contains invalid content type '" + var7.getContentType().toString() + "'. The UserInfo Response should return a JSON object (content type 'application/json') that contains a collection of name and value pairs of the claims about the authenticated End-User. Please ensure the UserInfo Uri in UserInfoEndpoint for Client Registration '" + userRequest.getClientRegistration().getRegistrationId() + "' conforms to the UserInfo Endpoint, as defined in OpenID Connect 1.0: 'https://openid.net/specs/openid-connect-core-1_0.html#UserInfo'";
            OAuth2Error oAuth2Error = new OAuth2Error("invalid_user_info_response", errorMessage, (String)null);
            throw new OAuth2AuthenticationException(oAuth2Error, oAuth2Error.toString(), var7);
        } catch (RestClientException var8) {
            oauth2Error = new OAuth2Error("invalid_user_info_response", "An error occurred while attempting to retrieve the UserInfo Resource: " + var8.getMessage(), (String)null);
            throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString(), var8);
        }
    }
    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;
    }
}

loadUser是核心方法,只用在業(yè)務(wù)上對(duì)其修改成符合自己的業(yè)務(wù)需求就行。

8. 配置securityConfig

http.oauth2Login()
                .userInfoEndpoint()
                .userService(new CustomOAuth2UserService());

9. 驗(yàn)證是否配置成功

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<form action="/oauth2/authorization/gitee" method="post" onsubmit="onsubmitFun()">
    <input type="submit" value="Gitee授權(quán)登錄">
</form>
</body>
</html>

以上就配置成功了。更多相關(guān)springsecurity第三方授權(quán)認(rèn)證內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring定時(shí)服務(wù)QuartZ原理及代碼案例

    Spring定時(shí)服務(wù)QuartZ原理及代碼案例

    這篇文章主要介紹了Spring定時(shí)服務(wù)QuartZ原理及代碼案例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Spring Aop注解實(shí)現(xiàn)

    Spring Aop注解實(shí)現(xiàn)

    本文我們通過Spring AOP和Java的自定義注解來實(shí)現(xiàn)日志的插入功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友一起看看吧,希望對(duì)你有所幫助
    2021-07-07
  • Spring Boot整合Elasticsearch實(shí)現(xiàn)全文搜索引擎案例解析

    Spring Boot整合Elasticsearch實(shí)現(xiàn)全文搜索引擎案例解析

    ElasticSearch作為基于Lucene的搜索服務(wù)器,既可以作為一個(gè)獨(dú)立的服務(wù)部署,也可以簽入Web應(yīng)用中。SpringBoot作為Spring家族的全新框架,使得使用SpringBoot開發(fā)Spring應(yīng)用變得非常簡單,在本案例中我們給大家介紹Spring Boot整合Elasticsearch實(shí)現(xiàn)全文搜索引擎
    2017-11-11
  • Java前后端任意參數(shù)類型轉(zhuǎn)換方式(Date、LocalDateTime、BigDecimal)

    Java前后端任意參數(shù)類型轉(zhuǎn)換方式(Date、LocalDateTime、BigDecimal)

    這篇文章主要介紹了Java前后端任意參數(shù)類型轉(zhuǎn)換方式(Date、LocalDateTime、BigDecimal),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Java編程中10個(gè)最佳的異常處理技巧

    Java編程中10個(gè)最佳的異常處理技巧

    這篇文章主要介紹了Java編程中10個(gè)最佳的異常處理技巧,在本文中,將討論Java異常處理最佳實(shí)踐,這些Java最佳實(shí)踐遵循標(biāo)準(zhǔn)的JDK庫,和幾個(gè)處理錯(cuò)誤和異常的開源代碼,這還是一個(gè)提供給java程序員編寫健壯代碼的便利手冊,需要的朋友可以參考下
    2015-01-01
  • Java線性結(jié)構(gòu)中棧、隊(duì)列和串的基本概念和特點(diǎn)詳解

    Java線性結(jié)構(gòu)中棧、隊(duì)列和串的基本概念和特點(diǎn)詳解

    前幾天小編給大家介紹了Java線性結(jié)構(gòu)中的鏈表,除了鏈表這種結(jié)構(gòu)之外,實(shí)際上還有棧、隊(duì)列、串等結(jié)構(gòu),那么這些結(jié)構(gòu)又有哪些特點(diǎn)呢,本文就給大家詳細(xì)的介紹一下,感興趣的小伙伴跟著小編一起來看看吧
    2023-07-07
  • Java利用Spire.Doc實(shí)現(xiàn)RTF轉(zhuǎn)換PDF的高效方案

    Java利用Spire.Doc實(shí)現(xiàn)RTF轉(zhuǎn)換PDF的高效方案

    在企業(yè)級(jí)應(yīng)用開發(fā)中,RTF格式雖因其良好的兼容性曾在文檔交換領(lǐng)域占據(jù)一席之地,但隨著移動(dòng)辦公和長期歸檔需求的增加,其跨平臺(tái)顯示不一致、易被篡改的弊端日益凸顯,本文將介紹如何利用Spire.Doc for Java這一強(qiáng)大的類庫實(shí)現(xiàn)將RTF轉(zhuǎn)換為PDF,需要的朋友可以參考下
    2026-03-03
  • javaweb分頁原理詳解

    javaweb分頁原理詳解

    這篇文章主要為大家詳細(xì)介紹了javaweb分頁的原理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • Java開發(fā)工具Eclipse使用技巧全局搜索和更替

    Java開發(fā)工具Eclipse使用技巧全局搜索和更替

    這篇文章主要介紹了Java開發(fā)工具Eclipse使用技巧全局搜索和更替,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • android中判斷服務(wù)或者進(jìn)程是否存在實(shí)例

    android中判斷服務(wù)或者進(jìn)程是否存在實(shí)例

    本篇文章主要介紹了android中判斷服務(wù)或者進(jìn)程是否存在實(shí)例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-05-05

最新評(píng)論

阿克苏市| 唐河县| 乾安县| 梓潼县| 墨竹工卡县| 长兴县| 贵州省| 揭西县| 谷城县| 凤庆县| 潞城市| 昌宁县| 阳东县| 沙坪坝区| 南宫市| 阳泉市| 彭山县| 嘉祥县| 密山市| 金塔县| 瑞安市| 千阳县| 黄梅县| 扬中市| 上杭县| 巴彦县| 台江县| 宜城市| 阜平县| 成武县| 合山市| 阜新市| 钟山县| 玉树县| 温州市| 福泉市| 宽甸| 昌乐县| 和平区| 湖州市| 双牌县|