码迷,mamicode.com
首页 > 编程语言 > 详细

springcloud中oauth工作流程

时间:2018-09-18 11:19:17      阅读:487      评论:0      收藏:0      [点我收藏+]

标签:odi   members   ace   tps   member   etc   bst   ext   exception   

1.第一步登录获取token

通过oauth服务,进行登录。返回token

 @ApiOperation(value="登录", notes="登录",httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    //@PostMapping("/generatorToken")
    @RequestMapping(value="/generatorToken")
    public ResponseEntity<OAuth2AccessToken> token(String username,String password, String vrifyCode, String captchaFlag) throws HttpRequestMethodNotSupportedException {
        if(captchaFlag != null && !captchaFlag.equals("")){
            boolean flag = doCaptchaValidate(captchaFlag,vrifyCode);
            if(!flag){
                throw new InvalidGrantException("验证码不正确!");
            }
        }
        Map<String, String> requestParameters = new HashMap<>();
        requestParameters.put("grant_type","password");//自己设置
        requestParameters.put("client_id","client_id");//自己设置
        requestParameters.put("client_secret","client_secret");//自己设置
        String clientId = (String)requestParameters.get("client_id");
        String grantType = (String)requestParameters.get("grant_type");
        Set<String> scopes = new HashSet<>();
        scopes.add("all");
        TokenRequest tokenRequest = new TokenRequest(requestParameters, clientId, scopes, grantType);

        ClientDetails client = this.clientDetailsService.loadClientByClientId(tokenRequest.getClientId());
        OAuth2RequestFactory oAuth2RequestFactory = authorizationServerEndpointsConfiguration.getEndpointsConfigurer().getOAuth2RequestFactory();
        OAuth2Authentication oAuth2Authentication = null;

        Map<String, String> parameters = new LinkedHashMap(tokenRequest.getRequestParameters());
        parameters.remove("password");
        Authentication userAuth = new UsernamePasswordAuthenticationToken(username, password);
        ((AbstractAuthenticationToken)userAuth).setDetails(parameters);
        try {
            userAuth = this.authenticationManager.authenticate(userAuth);
        } catch (AccountStatusException var8) {
            throw new InvalidGrantException(var8.getMessage());
        } catch (BadCredentialsException var9) {
            throw new InvalidGrantException(var9.getMessage());
        }

        if (userAuth != null && userAuth.isAuthenticated()) {
            OAuth2Request storedOAuth2Request = oAuth2RequestFactory.createOAuth2Request(client, tokenRequest);
            oAuth2Authentication =  new OAuth2Authentication(storedOAuth2Request, userAuth);
        } else {
            throw new InvalidGrantException("Could not authenticate user: " + username);
        }
        OAuth2AccessToken oAuth2AccessToken = authorizationServerTokenServices.createAccessToken(oAuth2Authentication);
        return this.getResponse(oAuth2AccessToken);
    }

 

第二步  自定义oauth拦截器,这里设置了

customPrincipalExtractor,下面粉红色代码
package com.ycsys.business.config;

import java.nio.charset.StandardCharsets;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter;
import org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator;
import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;

import com.ycsys.business.dto.ResponseEx;

/**
 * Created by lixiaoxin on 2017/9/25.
 *
 * @author lixiaoxin
 */
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    private static final Logger LOG = LoggerFactory.getLogger(ResourceServerConfig.class);

//    @Value("${security.oauth2.resource.user-info-uri}")
//    private String userInfoUri;

    @Resource
    private UserInfoTokenServices userInfoTokenServices;

    @Resource
    private CustomPrincipalExtractor customPrincipalExtractor;

    @Override
    public void configure(HttpSecurity http) throws Exception {

        //自定义oauth2拦截器
        OAuth2AuthenticationProcessingFilter f = new OAuth2AuthenticationProcessingFilter();
        OAuth2AuthenticationEntryPoint oAuth2AuthenticationEntryPoint = new OAuth2AuthenticationEntryPoint();
        oAuth2AuthenticationEntryPoint.setExceptionTranslator(webResponseExceptionTranslator());
        f.setAuthenticationEntryPoint(oAuth2AuthenticationEntryPoint);
        OAuth2AuthenticationManager o = new OAuth2AuthenticationManager();
        //dt.setTokenStore(tokenStore());
        userInfoTokenServices.setPrincipalExtractor(customPrincipalExtractor);
        o.setTokenServices(userInfoTokenServices);
        f.setAuthenticationManager(o);
        //为空情况自定义返回体
        http.exceptionHandling()
                .authenticationEntryPoint(
                        (request, response,authException)-> {
                        try {
                            ObjectMapper m = new ObjectMapper();
                            String json = m.writeValueAsString(new ResponseEx().error("token不能为空"));
                            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
                            response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
                            response.getWriter().write(json);
                        } catch (Exception e1) {
                            e1.printStackTrace();
                        }
        }
        )
                //.defaultAuthenticationEntryPointFor()
                //.accessDeniedHandler(accessDeniedHandler);    // You‘re using the autowired members above.
                .and()
                .authorizeRequests()
//                .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
//                    public <O extends FilterSecurityInterceptor> O postProcess(O fsi) {
//                        fsi.set
//                        return fsi;
//                    }})
                //.requestMatchers(CorsUtils::isCorsRequest).permitAll()
                .antMatchers("/swagger-ui.html","/webjars/**","/swagger-ui.html/**","/swagger-resources/**","/v2/**"
                ,"/rest/**","/geometry/**","/wechat/**","/files/**","/user/validateUserName","/user/registerFirst"
                ,"/user/registerSecond","/user/sendRegisterSMS","/user/sendFindPwdSMS","/user/findPwdFirst","/user/findPwdSecond","/user/PWUpdatePassword"
                ,"/user/sendBindingSMS","/ParkDynamics/**","/Animal/**","/AnimalType/**","/AnimalScience/**","/AnimalMusic/**",
                "/AnimalClass/**","/feedback/**","/Guide/**","/helpCenter/**","/Notice/**","/VoiceExplain/**","/WeChatReply/weChatRequest"
                ,"/ThemePavilions/**","/Activity/**","/AnimalFeed/**","/test/**","/location/findUserRealTimeLocation","/EmergencyStartup/**"
                ,"/convenientService/**","/traffic/**","/msg/**","/rulesRegulations/**","/ApeCource/**",
                "/EmergencyPlanModel/findByTypeName").permitAll()
                .anyRequest().authenticated() //开启网关和授权
                //.anyRequest().permitAll()//不需要通过网关和授权即可访问
                .and()
                .addFilterBefore(f, AbstractPreAuthenticatedProcessingFilter.class)
                .httpBasic();

    }

//    @Bean
//    // very important notice: method name should be exactly "userInfoTokenServices"
//    public ResourceServerTokenServices userInfoTokenServices() {
//        CustomUserInfoTokenService serv = new CustomUserInfoTokenService(userInfoUri, null);
//        return serv;
//    }

    //自定义返回体
    @Bean
    public WebResponseExceptionTranslator webResponseExceptionTranslator() {
        return new DefaultWebResponseExceptionTranslator() {

            @Override
            public ResponseEntity<OAuth2Exception> translate(Exception e) throws Exception {
                ResponseEntity<OAuth2Exception> responseEntity = super.translate(e);
//                OAuth2Exception body = responseEntity.getBody();
                HttpHeaders headers = new HttpHeaders();
                headers.setAll(responseEntity.getHeaders().toSingleValueMap());
                ResponseEx ex = new ResponseEx().error(ErrorCode.ERROR,"无效的token");
                return new ResponseEntity(ex, headers, responseEntity.getStatusCode());
            }
        };
    }

}

第三步 实现

PrincipalExtractor 
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.oauth2.resource.PrincipalExtractor;
import org.springframework.stereotype.Component;

import com.ycsys.business.common.EhCacheUtils;
import com.ycsys.business.entity.User;
import com.ycsys.business.repository.UserRepository;

/**
 * Created by lixiaoxin on 2018/2/5.
 */
@Component
public class CustomPrincipalExtractor implements PrincipalExtractor {

    @Autowired
    private UserRepository userRepository;

    private static final String[] PRINCIPAL_KEYS = new String[]{"user", "username", "userid", "user_id", "login", "id", "name"};

    @Override
    public Object extractPrincipal(Map<String, Object> map) {

        for(int i = 0; i < PRINCIPAL_KEYS.length; ++i) {
            String key = PRINCIPAL_KEYS[i];
            if (map.containsKey(key)) {
                if(key.equals("user")){
                    Object obj = map.get(key);
                    Map m = (Map) obj;
                    Integer id = (Integer) m.get("id");
                    Object object = EhCacheUtils.get("users", id.toString());
                    User user=null;
                    if(object==null){
                    	  user = userRepository.getById(id.longValue());
                          EhCacheUtils.put("users", id.toString(), user);
                    }else{
                    	user=(User)object;
                    }
                    return user;
                }else {
                    return map.get(key);
                }
            }
        }

        return null;
    }
}

  

第四部  如何使用

技术分享图片

springcloud中oauth工作流程

标签:odi   members   ace   tps   member   etc   bst   ext   exception   

原文地址:https://www.cnblogs.com/longsanshi/p/9667141.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!