oliver_105397
Ultraman_TigaSang
采纳率80%
2019-01-11 11:32 阅读 943
已采纳

spring-security-oauth2:intercept-url的access字段IS_AUTHENTICATED_FULLY无法使用了

最近把spring-security-oauth2的版本更新到了最新版,发现路径限制的access属性已经不能再使用原有的字符串和hasRole等函数了,百度上找的都是旧版的用法,官网也没怎么看懂,求大佬支招
下面两种方式都试过了,还是没法启动。

<security:intercept-url pattern="/oauth/token" access="hasRole('ROLE_USER')" />
<security:intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />

<security:intercept-url pattern="/api/**" access="hasRole('ROLE_USER')" />
<security:intercept-url pattern="/api/**" access="IS_AUTHENTICATED_FULLY" />
Caused by: java.lang.IllegalArgumentException: Unsupported configuration attributes: [hasRole('ROLE_USER')]
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.afterPropertiesSet(AbstractSecurityInterceptor.java:176)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1804)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1741)
    ... 47 more
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

2条回答 默认 最新

  • 已采纳
    oliver_105397 Ultraman_TigaSang 2019-01-15 11:33

    放棄了xml的配置方式,改為spring boot項目了。

    授權配置:

    package com.hbk.config;
    
    import javax.sql.DataSource;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.HttpMethod;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
    import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
    import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
    import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
    import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
    import org.springframework.security.oauth2.provider.token.TokenStore;
    import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
    
    import com.hbk.service.impl.MyUserDetailsService;
    
    @Configuration
    @EnableAuthorizationServer
    public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
    
        private static final String PROP_CLIENTID = "client";
        private static final int PROP_TOKEN_VALIDITY_SECONDS = 43200;
    
        @Autowired
        private DataSource dataSource;
    
        @Autowired
        private MyUserDetailsService userDetailsService;
    
        @Bean
        public TokenStore tokenStore() {
            return new JdbcTokenStore(dataSource);
        }
    
        @Autowired
        private AuthenticationManager authenticationManager;
    
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints
                .tokenStore(tokenStore())
                /*使用密碼模式的時候需要此項*/
                .authenticationManager(authenticationManager)
                /*使用refresh_token需要添加此配置,否則無法寫入數據庫*/
                .userDetailsService(userDetailsService)
                /*允許的接口訪問類型*/
                .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
        }
    
        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            /*因為強制使用了加密模式,所以secret的格式也需要經過加密才可以正常通過驗證*/
            String finalSecret = new BCryptPasswordEncoder().encode("123456");
            clients.inMemory()
                .withClient(PROP_CLIENTID)
                .scopes("all")
                .authorities("ROLE_ADMIN", "ROLE_USER")
                .authorizedGrantTypes("password", "refresh_token")
                .secret(finalSecret)
                .authorities("oauth2")
                .accessTokenValiditySeconds(PROP_TOKEN_VALIDITY_SECONDS);
        }
    
        @Override
        public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
            security
                .checkTokenAccess("permitAll()")
                .tokenKeyAccess("permitAll()")
                /*允許表單提交*/
                .allowFormAuthenticationForClients();
        }
    }
    

    資源服務:

    package com.hbk.config;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
    import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
    
    @Configuration
    @EnableResourceServer
    public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
    
        @Autowired
        private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
    
        @Bean
        public CustomLogoutSuccessHandler customerLogoutSuccessHandler() {
            return new CustomLogoutSuccessHandler();
        }
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.exceptionHandling()
                .authenticationEntryPoint(customAuthenticationEntryPoint)
                .and()
                .logout()
                .logoutUrl("/oauth/logout")
                .logoutSuccessHandler(customerLogoutSuccessHandler())
                .and()
                .authorizeRequests()
                .antMatchers("/imgs/**").permitAll()
                .antMatchers("/api/**").authenticated();
        }
    }
    

    自定義logout處理:

    package com.hbk.config;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.oauth2.common.OAuth2AccessToken;
    import org.springframework.security.oauth2.provider.token.TokenStore;
    import org.springframework.security.web.authentication.AbstractAuthenticationTargetUrlRequestHandler;
    import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
    import org.springframework.util.StringUtils;
    
    
    public class CustomLogoutSuccessHandler extends AbstractAuthenticationTargetUrlRequestHandler implements LogoutSuccessHandler {
    
        private static final String BEARER_AUTHENTICATION = "Bearer";
        private static final String HEADER_AUTHORIZATION = "authorization";
    
        @Autowired
        private TokenStore tokenStore;
    
        @Override
        public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
                throws IOException, ServletException {
            String token = request.getHeader(HEADER_AUTHORIZATION);
            if (StringUtils.hasLength(token) && token.startsWith(BEARER_AUTHENTICATION)) {
                OAuth2AccessToken accessToken = tokenStore.readAccessToken(token.split(" ")[0]);
                if (accessToken != null) {
                    tokenStore.removeAccessToken(accessToken);
                }
            }
            response.setStatus(HttpServletResponse.SC_OK);
        }
    
    }
    

    自定義授權捕獲:

    package com.hbk.config;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.web.AuthenticationEntryPoint;
    import org.springframework.stereotype.Component;
    
    @Component
    public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
    
        private final Logger log = LoggerFactory.getLogger(CustomAuthenticationEntryPoint.class);
    
        @Override
        public void commence(HttpServletRequest request, HttpServletResponse response,
                AuthenticationException authException) throws IOException, ServletException {
            log.info("Pre-authenticated entry point called. Rejecting access");
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Access Denied");
        }
    
    }
    

    Web安全配置:

    package com.hbk.config;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
    import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
    import org.springframework.security.config.annotation.web.builders.WebSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler;
    
    import com.hbk.service.impl.MyUserDetailsService;
    
    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private MyUserDetailsService userDetailsService;
    
        @Bean
        PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    
        //配置全局设置
        @Autowired
        private void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            //设置UserDetailsService以及密码规则
            auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
        }
    
        @Override
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().antMatchers("/test");
        }
    
        @Bean
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean() ;
        }
    
        //开启全局方法拦截
        @EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true)
        public static class GlobalSecurityConfiguration extends GlobalMethodSecurityConfiguration {
            @Override
            protected MethodSecurityExpressionHandler createExpressionHandler() {
                return new OAuth2MethodSecurityExpressionHandler();
            }
        }
    }
    

    UserDetailsService實現類:

    package com.hbk.service.impl;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.stereotype.Service;
    import org.springframework.util.StringUtils;
    
    import com.hbk.pojos.Permission;
    import com.hbk.pojos.User;
    import com.hbk.service.PermissionService;
    import com.hbk.service.UserService;
    
    @Service
    public class MyUserDetailsService implements UserDetailsService {
    
        @Autowired
        private UserService userService;
    
        @Autowired
        private PermissionService permissionService;
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            User user = userService.getByUsername(username);
            List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
            if (user != null) {
                //获取用户的授权
                List<Permission> permissions = permissionService.findByAdminUserId(user.getId());
                for (Permission permission : permissions) {
                    if (permission != null && StringUtils.hasLength(permission.getName())) {
                        GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getName());
                        authorities.add(grantedAuthority);
                    }
                }
            }
            org.springframework.security.core.userdetails.User userDetail = new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), authorities);
            return userDetail;
        }
    }
    

    感謝這位老哥:(https://blog.csdn.net/Ybt_c_index/article/details/85067321 "")

    点赞 评论 复制链接分享
  • jncqlc jncqlc 2019-04-28 16:12

    点赞 评论 复制链接分享

相关推荐