How do I remove the ROLE_ prefix from Spring Security with JavaConfig?

匿名 (未验证) 提交于 2019-12-03 01:25:01

问题:

I'm trying to remove the "ROLE_" prefix in Spring Security. The first thing I tried was:

http.servletApi().rolePrefix("");

That didn't work, so I tried creating a BeanPostProcessor as suggested in http://docs.spring.io/spring-security/site/migrate/current/3-to-4/html5/migrate-3-to-4-jc.html#m3to4-role-prefixing-disable. That didn't work either.

Finally, I tried creating my own SecurityExpressionHandler:

  @Override   protected void configure(HttpSecurity http) throws Exception {       http           .authorizeRequests()           .expressionHandler(webExpressionHandler())           .antMatchers("/restricted").fullyAuthenticated()           .antMatchers("/foo").hasRole("mycustomrolename")           .antMatchers("/**").permitAll();   }    private SecurityExpressionHandler webExpressionHandler() {       DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();       defaultWebSecurityExpressionHandler.setDefaultRolePrefix("");       return defaultWebSecurityExpressionHandler;   }

However, this doesn't work either. If I use "hasAuthority(roleName)" instead of hasRole, it works as expected.

Is it possible to remove the ROLE_ prefix from Spring Security's hasRole check?

回答1:

Starting from Spring 4.2, you can define the prefix with a single bean, as described here: https://github.com/spring-projects/spring-security/issues/4134

@Bean GrantedAuthorityDefaults grantedAuthorityDefaults() {     return new GrantedAuthorityDefaults(""); // Remove the ROLE_ prefix }


回答2:

The following configuration works for me.

@Override public void configure(WebSecurity web) throws Exception {     web.expressionHandler(new DefaultWebSecurityExpressionHandler() {         @Override         protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, FilterInvocation fi) {             WebSecurityExpressionRoot root = (WebSecurityExpressionRoot) super.createSecurityExpressionRoot(authentication, fi);             root.setDefaultRolePrefix(""); //remove the prefix ROLE_             return root;         }     }); }


回答3:

If you are prior to 4.2 and are using so called voters (you are if you use annotations like @hasRole etc) then you need to define below beans in the context:

@Bean public DefaultMethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler() {     DefaultMethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler = new DefaultMethodSecurityExpressionHandler();     defaultMethodSecurityExpressionHandler.setDefaultRolePrefix("");     return defaultMethodSecurityExpressionHandler; }  @Bean public DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler() {     DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();     defaultWebSecurityExpressionHandler.setDefaultRolePrefix("");     return defaultWebSecurityExpressionHandler; }

These beans are used to create evaluation context for spell expressions and they have a defaultRolePrefix set to 'ROLE_'. Although it depends on your use case. This one worked for me and above didn't.

EDIT: answering question about xml configuration -> of course it can be done in xml. Everything done in java config can be written in xml configuration. Here is example (although I did not test it so there might be a typo or something):

                      


回答4:

It appears the new GrantedAuthorityDefaults will change the prefix for the DefaultWebSecurityExpressionHandler and the DefaultMethodSecurityExpressionHandler, but it doesn't modify the RoleVoter.rolePrefix that is setup from @EnableGlobalMethodSecurity.

The RoleVoter.rolePrefix is what is used for @Secured("ADMIN") style of method security.

So along with the GrantedAuthorityDefaults, I had to also add this CustomGlobalMethodSecurity class to override the defaults for RoleVoter.

@Configuration @EnableGlobalMethodSecurity(securedEnabled = true) public class CustomGlobalMethodSecurity extends GlobalMethodSecurityConfiguration {      protected AccessDecisionManager accessDecisionManager() {         AffirmativeBased accessDecisionManager = (AffirmativeBased) super.accessDecisionManager();          //Remove the ROLE_ prefix from RoleVoter for @Secured and hasRole checks on methods         accessDecisionManager.getDecisionVoters().stream()                 .filter(RoleVoter.class::        
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!