1. 程式人生 > >基於oauth2.0的單點登入

基於oauth2.0的單點登入

1、在認證中心進行系統註冊

這裡寫圖片描述

2、 根據註冊引數,在系統中設定引數

oauth.oa.key=admineap
oauth.oa.secret=99aaa0bed18a4533bb6ca3fbf91739fd
oauth.oa.scope=billjiang
oauth.oa.authorize_url=http://localhost:8105/oauth/authorize?client_id=%s&response_type=code&redirect_uri=%s&scope=%s
oauth.oa.access_token_url=http://localhost:8105
/oauth/token?grant_type=authorization_code oauth.oa.user_url=http://localhost:8105/oauth/user oauth.oa.binding_url=http://localhost:8081/AdminEAP-web/oauth/appBinding

3、pom.xml引入scribe

   <dependency>
            <groupId>org.scribe</groupId>
            <artifactId>scribe</artifactId
>
<version>1.3.7</version> </dependency>

4、編寫相關類

類結構圖

5、部分類的方法

OAuthConfig:引數配置入口,以及service的初始化

package com.cnpc.framework.conf;

import com.cnpc.framework.oauth.common.CustomOAuthService;
import com.cnpc.framework.oauth.common.OAuthTypes;
import com.cnpc.framework.oauth.esp.EspApi;
import
com.cnpc.framework.oauth.github.GithubApi; import com.cnpc.framework.utils.PropertiesUtil; import org.scribe.builder.ServiceBuilder; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.ArrayList; /** * Created by billJiang on 2017/1/15. * e-mail:[email protected] qq:475572229 */ @Configuration public class OAuthConfig { @Value("${oauth.callback.url}") String callback_url; /** * github配置 */ @Value("${oauth.github.key}") String github_key; @Value("${oauth.github.secret}") String github_secret; @Value("${oauth.github.state}") String github_state; @Bean public GithubApi githubApi(){ return new GithubApi(github_state); } @Bean public CustomOAuthService getGithubOAuthService(){ return (CustomOAuthService)new ServiceBuilder() .provider(githubApi()) .apiKey(github_key) .apiSecret(github_secret) .callback(String.format(callback_url, OAuthTypes.GITHUB)) .build(); } //------oa add by billjiang @Value("${oauth.oa.key}") String oa_key; @Value("${oauth.oa.secret}") String oa_secret; @Value("${oauth.oa.scope}") String oa_scope; @Value("${oauth.oa.btnclass}") String oa_btnclass; @Value("${oauth.oa.authorize_url}") String oa_authorize_url; @Value("${oauth.oa.access_token_url}") String oa_access_token_url; @Value("${oauth.oa.user_url}") String oa_user_url; @Value("${oauth.oa.binding_url}") String oa_binding_url; @Bean public EspApi espApi(){ return new EspApi(oa_authorize_url,oa_access_token_url,oa_user_url,oa_btnclass); } @Bean public CustomOAuthService getEspOAuthService(){ return (CustomOAuthService) new ServiceBuilder() .provider(espApi()) .apiKey(oa_key) .apiSecret(oa_secret) .scope(oa_scope) .callback(oa_binding_url) .build(); } }

CustomOAuthService:服務介面

public interface CustomOAuthService extends OAuthService {
    String getOAuthType();
    String getAuthorizationUrl();
    OAuthUser getOAuthUser(Token accessToken);
    String getUserName(String accessToken);
 }

EspOAuthService:操作服務類

package com.cnpc.framework.oauth.esp;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cnpc.framework.oauth.common.CustomOAuthService;
import com.cnpc.framework.oauth.common.OAuthTypes;
import com.cnpc.framework.oauth.entity.OAuthUser;
import org.scribe.model.*;
import org.scribe.oauth.OAuth20ServiceImpl;

/**
 * @author billjiang [email protected]
 * @create 18-4-6
 */
public class EspOAuthService extends OAuth20ServiceImpl implements CustomOAuthService {

    private String userUrl;
    private String btnClass;
    private final EspApi api;
    private final OAuthConfig config;
    private final String authorizationUrl;

    public EspOAuthService(EspApi api, OAuthConfig config) {
        super(api,config);
        this.api=api;
        this.config=config;
        this.authorizationUrl=this.api.getAuthorizationUrl(config);
        this.userUrl=this.api.getUserUrl();
        this.btnClass=this.api.getBtnClass();
    }


    @Override
    public String getOAuthType() {
        return OAuthTypes.OA;
    }

    @Override
    public String getAuthorizationUrl() {
        return this.authorizationUrl;
    }

    @Override
    public OAuthUser getOAuthUser(Token accessToken) {
        OAuthRequest request = new OAuthRequest(Verb.GET, this.userUrl);
        this.signRequest(accessToken, request);
        Response response = request.send();
        OAuthUser oAuthUser = new OAuthUser();
        oAuthUser.setoAuthType(getOAuthType());
        JSONObject result = JSON.parseObject(response.getBody());
        oAuthUser.setUserName(result.get("name").toString());
        return oAuthUser;
    }

    @Override
    public String getUserName(String accessToken) {
        OAuthRequest request = new OAuthRequest(Verb.GET, this.userUrl);
        request.addQuerystringParameter("access_token", accessToken);
        Response response = request.send();
        JSONObject result = JSON.parseObject(response.getBody());
        return result.get("name").toString();
    }
}

EspAPI:構造API

package com.cnpc.framework.oauth.esp;

import org.scribe.builder.api.DefaultApi20;
import org.scribe.extractors.AccessTokenExtractor;
import org.scribe.extractors.TokenExtractor20Impl;
import org.scribe.model.OAuthConfig;
import org.scribe.model.Verb;
import org.scribe.oauth.OAuthService;
import org.scribe.utils.OAuthEncoder;

/**
 * @author billjiang [email protected]
 * @create 18-4-6
 */
public class EspApi extends DefaultApi20 {

    private String authorize_url;
    private String access_token_url;
    private String user_url;
    private String btn_class;

    public EspApi(String authorize_url, String access_token_url, String user_url, String btn_class) {
        this.authorize_url = authorize_url;
        this.access_token_url = access_token_url;
        this.user_url = user_url;
        this.btn_class = btn_class;
    }

    @Override
    public String getAccessTokenEndpoint() {
        return this.access_token_url;
    }

    public AccessTokenExtractor getAccessTokenExtractor() {
        return new EspTokenExtractor();
    }

    @Override
    public Verb getAccessTokenVerb() {
        return Verb.POST;
    }

    @Override
    public String getAuthorizationUrl(OAuthConfig config) {
        return String.format(this.authorize_url, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), config
                .getScope());
    }

    @Override
    public OAuthService createService(OAuthConfig config) {
        return new EspOAuthService(this, config);
    }

    public String getUserUrl() {
        return this.user_url;
    }


}

EspTokenExtractor:解析token

public class EspTokenExtractor implements AccessTokenExtractor {
    @Override
    public Token extract(String response) {
        Preconditions.checkEmptyString(response, "Response body is incorrect. Can't extract a token from an empty string");
        Matcher matcher = Pattern.compile("access_token").matcher(response);
        if (matcher.find()) {
            String token = JSONObject.parseObject(response).getString("access_token");
            return new Token(token, "", response);
        } else {
            throw new OAuthException("Response body is incorrect. Can't extract a token from this: '" + response + "'", (Exception)null);
        }
    }
}

6、編寫系統繫結和單點登入方法

系統繫結:

 //-------------oa繫結系統,生成token--------------------
    @RequestMapping(value = "/oauth/appBinding")
    @ResponseBody
    public String appBinding(@RequestParam(value = "code") String code, HttpServletRequest request) {
        try {
            CustomOAuthService oAuthService = oAuthServices.getOAuthService(OAuthTypes.OA);
            Token accessToken = oAuthService.getAccessToken(null, new Verifier(code));
            return accessToken.getToken();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

系統登入:

 //-------------oa單點登入系統--------------------
    @RequestMapping(value = "/oauth/appLogin")
    public String appLogin(@RequestParam(value = "token") String access_token, @RequestParam(value = "source") String source) {
        if(!source.equals("oaplus")){
            return LOGIN_PAGE;
        }
        CustomOAuthService oAuthService = oAuthServices.getOAuthService(OAuthTypes.OA);
        String userName = oAuthService.getUserName(access_token);
        userName=getUserNameWithoutDomain(userName);
        //登入系統,繞過密碼和驗證碼
        User user = userService.getUserByLoginName(userName);
        return loginByAuth(user);
    }

    public String getUserNameWithoutDomain(String userName) {
        if (userName.isEmpty())
            return userName;
        userName = userName.replaceAll("\\\\\\\\", "\\\\");
        if (userName.indexOf("\\") > -1)
            userName = userName.split("\\\\")[1].toString();
        return userName;
    }