基于oauth2.0的单点登录

1、在认证中心进行系统注册

基于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.scribegroupId>
            <artifactId>scribeartifactId>
             <version>1.3.7version>
   dependency>

4、编写相关类

基于oauth2.0的单点登录_第2张图片

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;
    }

你可能感兴趣的:(系统安全)