weixin_39713503 2018-09-29 02:23
浏览 2191

spring security和spring oauth结合后 spring security配置不管用了

    spring security
@Configuration
@EnableResourceServer
public class AppWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    @Autowired
    private ZuulProperties zuulProperties;
    @Autowired
    private AuthenticationSuccessHandler appAuthenticationSuccessHandler;
    @Autowired
    private AuthenticationFailureHandler appAuthenticationFailureHandler;
    @Autowired
    private AccessDeniedHandler appAccessDeniedHandler;

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        AuthenticationManager manager = super.authenticationManagerBean();
        return manager;
    }



    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers(HttpMethod.GET,zuulProperties.getAuth().toGetAdapter())
            .permitAll()
            .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.POST,zuulProperties.getAuth().toPostAdapter())
                .permitAll()
            .and()
                .authorizeRequests()
                .anyRequest()
                .authenticated()
            .and()
                .exceptionHandling().accessDeniedHandler(appAccessDeniedHandler)
            .and()
                .csrf().disable();
    }

spring oauth相关

 @Configuration
@EnableAuthorizationServer
public class AppAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private final AuthenticationManager authenticationManager;
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private ZuulProperties zuulProperties;
    @Autowired
    private TokenStore tokenStore ;
    @Autowired(required = false)
    private JwtAccessTokenConverter jwtAccessTokenConverter;
    @Autowired(required = false)
    private TokenEnhancer jwtTokenEnhancer;
    @Autowired
    private PasswordEncoder passwordEncoder;

    public AppAuthorizationServerConfig(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }


    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        InMemoryClientDetailsServiceBuilder builder = clients.inMemory();
        OAuth2ClientProperties[] clientProperties = zuulProperties.getOauth().getClients();
        if(ArrayUtils.isNotEmpty(zuulProperties.getOauth().getClients())) {
            for (OAuth2ClientProperties oAuth2ClientProperties : clientProperties) {
                 builder.withClient(oAuth2ClientProperties.getClientId())
                   .secret(oAuth2ClientProperties.getClientSecret())
                   //token有效时间
                   .accessTokenValiditySeconds(oAuth2ClientProperties.getAccessTokenValiditySeconds())
                   //验证模式
                   .authorizedGrantTypes("password","authorization_code","client_credentials","implicit","refresh_token")
                   //刷新时间
                   .refreshTokenValiditySeconds(3600*24*100)
                    //跳转地址
                   .redirectUris("ws.28ph.cn")
                   //权限
                   .scopes("all");
            }
        } 
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager)
                .tokenStore(tokenStore)
                .userDetailsService(userDetailsService)
                .reuseRefreshTokens(true);
        if(jwtAccessTokenConverter != null && jwtTokenEnhancer!=null) {
            TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
            List<TokenEnhancer> tokenEnhancers = new ArrayList<>();
            tokenEnhancers.add(jwtTokenEnhancer);
            tokenEnhancers.add(jwtAccessTokenConverter);
            enhancerChain.setTokenEnhancers(tokenEnhancers);
            endpoints
                    .tokenEnhancer(enhancerChain)
                    .accessTokenConverter(jwtAccessTokenConverter);
        }
    }


    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.allowFormAuthenticationForClients()
                .passwordEncoder(passwordEncoder)
                .tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()");
    }

}

问题的产生:我在spring security配置了几个不需要拦截的uri,但是加入spring oauth 全部被拦截了,如果删掉@EnableResourceServer会出现 发出来的token 认证不了url的问题。。

然后我想大不了不用spring oauth 自带的发token方式。然后我在spring security的成功handler上下发token ,以下是代码

/**
 * 认证成功跳转
 * @author w4837
 *
 */
@Component(value = "AppAuthenticationSuccessHandler")
@Slf4j
public class AppAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private ClientDetailsService clientDetailsService;
    @Autowired
    private AuthorizationServerTokenServices authorizationServerTokenServices;



    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
                    HttpServletResponse httpServletResponse, Authentication authentication)
            throws IOException, ServletException {
        log.info("登陆成功");
        String header = httpServletRequest.getHeader("Authorization");
        //请求头包含Authorization 并且以"Basic "开始
        if (header == null || !header.startsWith("Basic ")) {
            throw new UnapprovedClientAuthenticationException("请求头中无Authorization信息");
        }

        try {
            String[] tokens = extractAndDecodeHeader(header, httpServletRequest);
            assert tokens.length == 2;

            String clientId = tokens[0];
            String clientSecret = tokens[1];
            ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
            if(clientDetails == null) {
                throw new UnapprovedClientAuthenticationException("clientId:"+clientId+"对应的信息不存在。");
            }else if(!StringUtils.equals(clientSecret, clientDetails.getClientSecret())) {
                throw new UnapprovedClientAuthenticationException("clientId:"+clientId+"对应的信息不匹配。");
            }
            @SuppressWarnings("unchecked")
            TokenRequest tokenRequest = new TokenRequest(MapUtils.EMPTY_MAP, clientId, clientDetails.getScope(),"custom");

            OAuth2Request auth2Request = tokenRequest.createOAuth2Request(clientDetails);

            OAuth2Authentication auth2Authentication = new OAuth2Authentication(auth2Request, authentication);

            OAuth2AccessToken createAccessToken = authorizationServerTokenServices.createAccessToken(auth2Authentication);
            // 判断需要的返回类型
            httpServletResponse.setContentType(ZuulAppConstant.CONTENT_TYPE_JSON);
            httpServletResponse.getWriter().write(objectMapper.writeValueAsString(createAccessToken));
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    /**
     * 解析header中编码后的数据
     *
     * @param header
     * @param request
     * @return
     * @throws IOException
     */
    private String[] extractAndDecodeHeader(String header, HttpServletRequest request) throws IOException {

        byte[] base64Token = header.substring(6).getBytes("UTF-8");
        byte[] decoded;
        try {
            decoded = Base64.decode(base64Token);
        } catch (IllegalArgumentException e) {
            throw new BadCredentialsException("Failed to decode basic authentication token");
        }

        String token = new String(decoded, "UTF-8");

        int delim = token.indexOf(":");

        if (delim == -1) {
            throw new BadCredentialsException("Invalid basic authentication token");
        }
        return new String[] { token.substring(0, delim), token.substring(delim + 1) };
    }

结果 启动还是报循环依赖的错误


***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

┌─────┐
|  appAuthorizationServerConfig defined in file [F:\yulece_aike_ideaword\app-management\app-management-zuul\target\classes\com\yulece\app\management\zuul\authorization\AppAuthorizationServerConfig.class]
↑     ↓
|  appWebSecurityConfigurerAdapter (field private org.springframework.security.web.authentication.AuthenticationSuccessHandler com.yulece.app.management.zuul.authorization.AppWebSecurityConfigurerAdapter.appAuthenticationSuccessHandler)
↑     ↓
|  AppAuthenticationSuccessHandler (field private org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices com.yulece.app.management.zuul.authorization.handler.AppAuthenticationSuccessHandler.defaultAuthorizationServerTokenServices)
↑     ↓
|  org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerEndpointsConfiguration (field private java.util.List org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerEndpointsConfiguration.configurers)
└─────┘

  • 写回答

0条回答

    报告相同问题?

    悬赏问题

    • ¥15 求解 yolo算法问题
    • ¥15 虚拟机打包apk出现错误
    • ¥30 最小化遗憾贪心算法上界
    • ¥15 用visual studi code完成html页面
    • ¥15 聚类分析或者python进行数据分析
    • ¥15 三菱伺服电机按启动按钮有使能但不动作
    • ¥15 js,页面2返回页面1时定位进入的设备
    • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
    • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
    • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝