首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SpelEvaluationException解释ResourceServerConfigurerAdapter中的“访问”字符串

SpelEvaluationException解释ResourceServerConfigurerAdapter中的“访问”字符串
EN

Stack Overflow用户
提问于 2015-03-25 20:57:55
回答 1查看 2K关注 0票数 1

对此有什么想法吗?

来自Tomcat:

代码语言:javascript
复制
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1011E:(pos 8): Method call: Attempted to call method throwOnError(java.lang.Boolean) on null context object

退回客户:

代码语言:javascript
复制
java.lang.IllegalArgumentException: Failed to evaluate expression '#oauth2.throwOnError(#oauth2.hasScope('read') and #oauth2.hasScope('write') and #oauth2.hasAnyRole('ROLE_USER','ROLE_ADMIN'))'
    org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:13)
    org.springframework.security.web.access.expression.WebExpressionVoter.vote(WebExpressionVoter.java:34)
    org.springframework.security.web.access.expression.WebExpressionVoter.vote(WebExpressionVoter.java:18)
    org.springframework.security.access.vote.UnanimousBased.decide(UnanimousBased.java:77)

我向我的授权服务器/oauth/token发送一个帖子,并得到一个令牌。

如果我接受这个令牌并向资源服务器的GET请求添加一个授权:承载头,我就会得到这个错误。

在我的ResourceServerConfigurerAdapter子类中,它炸掉的一行如下所示:

代码语言:javascript
复制
public void configure(HttpSecurity http) throws Exception {

    http
    .authorizeRequests()
    .antMatchers("/api/**")

.access("#oauth2.hasScope('read') and #oauth2.hasScope('write') and #oauth2.hasAnyRole('ROLE_USER','ROLE_ADMIN')")

    .accessDecisionManager(accessDecisionManager())
    .anyRequest()
    .fullyAuthenticated();

我知道资源服务器识别令牌,因为如果我忽略它,就会得到正确的错误。如果我编造了一个假的,那么我得到了“无效令牌”消息,这是预期的。如果我使用实际的令牌,Spring将跳入并在.access()上爆炸。

提前感谢您的帮助。我把我的ResourceReserver的代码放在下面:

代码语言:javascript
复制
@Configuration
@EnableWebSecurity
@EnableResourceServer
public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {

    @Autowired
    private OAuth2AuthenticationEntryPoint oAuth2AuthenticationEntryPoint;


    @Autowired
    private ResourceServerTokenServices tokenServices;

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    @Qualifier("oauth2ResourceId")
    private String oauth2ResourceId; 

    @Autowired
    @Qualifier("oauth2Realm")
    private String oauth2Realm;

    @Bean
    OAuth2AuthenticationEntryPoint oAuth2AuthenticationEntryPoint() {
        final OAuth2AuthenticationEntryPoint entryPoint = new OAuth2AuthenticationEntryPoint();
        entryPoint.setRealmName(oauth2Realm);
        entryPoint.setTypeName("Basic");
        return entryPoint;
    }

    private AccessDecisionManager accessDecisionManager() {
        return new UnanimousBased(Arrays.<AccessDecisionVoter>asList(new ScopeVoter(),
                                                                     new AuthenticatedVoter(),
                                                                     new WebExpressionVoter()));
    }

    private AuthenticationManager getAuthenticationManager() {
        final OAuth2AuthenticationManager oAuth2AuthenticationManager = new OAuth2AuthenticationManager();
        oAuth2AuthenticationManager.setTokenServices(tokenServices);

        return oAuth2AuthenticationManager;
    }

    public void configure(HttpSecurity http) throws Exception {

        http
        .authorizeRequests()
        .antMatchers("/api/**")
        .access("#oauth2.hasScope('read') and #oauth2.hasScope('write') and #oauth2.hasAnyRole('ROLE_USER','ROLE_ADMIN')")
        .accessDecisionManager(accessDecisionManager())
        .anyRequest()
        .fullyAuthenticated();

        http
        .anonymous()
        .disable();

        http
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.NEVER);

        http
        .logout()
        .logoutUrl("/oauth/logout")
        .logoutSuccessHandler(logoutSuccessHandler())
        .invalidateHttpSession(true);

/*        
        http
        .requiresChannel()
        .antMatchers("/oauth/api/**")
        .requiresSecure();

        http
        .portMapper()
        .http(8080)
        .mapsTo(8443);
*/  

    }


    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources
        .authenticationManager(getAuthenticationManager())
        .tokenServices(tokenServices)
        .tokenStore(tokenStore)
        .resourceId(oauth2ResourceId);
    }

    private LogoutSuccessHandler logoutSuccessHandler() {
        return new OAuth2SuccessLogoutHandler(tokenStore);
    }

    static final class OAuth2SuccessLogoutHandler implements LogoutSuccessHandler {

        private final TokenStore tokenStore;

        public OAuth2SuccessLogoutHandler(final TokenStore tokenStore) {
            this.tokenStore = tokenStore;
        }

        @Override
        public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
               request.toString();
        }


    }

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-03-25 21:40:22

hasAnyRole()方法与OAuth2无关,因此不在#oauth2变量上(它位于根上,因此不需要限定它)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29266377

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档