如何更改Spring Security中的拦截URL而无需重新部署应用程序?

时间:2017-11-29 03:59:21

标签: spring spring-security

我目前正在尝试构建一个实现Spring安全性的数据库用户界面,但我仍然坚持如何更改来自access = hasRole(' ROLE_ADMIN')的拦截网址访问权限= denyAll并拒绝任何用户访问该特定页面而无需我退出。

这是我的WebSecurityConfig类:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private DataSource dataSource;

@Value("${users-by-username-query}")
private String usersQuery;

@Value("${authorities-by-username-query}")
private String authoritiesQuery;

@Autowired
private MyAuthenticationHandler myAuthenticationHandler;


private CustomAccessDecisionManager customAccessDecisionManager;

@Autowired
private Service service;


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

    List<UrlRole> viewPermissions = service.findAllUrlRole();
    System.out.println("Return from service class with size "+viewPermissions.size());
    ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry interceptUrlRegistry = http
//              .authorizeRequests().antMatchers("/","/hello.html","/footer.jsp","/header.jsp","/sidebar.jsp","/reg_issuer.jsp","/reg_user.jsp","/rest/**","/IssuerList.jsp","/loginSecurity","/index.jsp","/verify_otp.jsp")
            .authorizeRequests().antMatchers("/","/rest/**")
            .permitAll();

     for (int i = 0;i<viewPermissions.size();i++) {

         String url = viewPermissions.get(i).getUrl();

         String string = "";
         if(viewPermissions.get(i).getRole().equalsIgnoreCase("denyAll")){

             string = viewPermissions.get(i).getRole(); 

         }else{

             string = "hasRole('"+viewPermissions.get(i).getRole()+"')";
             for (int j = 0;j<viewPermissions.size();j++) {
                 if(j!=i && viewPermissions.get(j).getUrl().equalsIgnoreCase(url) ){
                     string+=" or hasRole('"+viewPermissions.get(j).getRole()+"')";

                 }

             }

         }



         interceptUrlRegistry.antMatchers(viewPermissions.get(i).getUrl()).access(string);
     }

     interceptUrlRegistry.anyRequest().authenticated()
     .and()
     .formLogin()
     .loginPage("/login").successHandler(myAuthenticationHandler)
     .usernameParameter("username")
    .passwordParameter("password")
     .permitAll()
     .and()
 .logout()
     .permitAll()
     .and()
 .exceptionHandling()
    .accessDeniedPage("/403");

}

@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {

    auth
        .jdbcAuthentication().dataSource(dataSource)
        .usersByUsernameQuery(usersQuery)
        .authoritiesByUsernameQuery(authoritiesQuery);
}

@Override
public void configure(WebSecurity web) throws Exception {
    web
       .ignoring()
       .antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**", "/assets/**");


}
}

目前我正在循环使用&#34; antMatchers(viewPermissions.get(i).getUrl())。access(string)&#34;从数据库中获取url和角色,但只有在我第一次在wildfly中部署时才会这样做。这就是为什么除非我重新启动wildfly服务器,否则不会实现新的url访问。

无论如何都要实现它而不必重新启动服务器?

我得到的答案我的工作如下:

这是我的新WebSecurityConfig类:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private DataSource dataSource;

@Value("${users-by-username-query}")
private String usersQuery;

@Value("${authorities-by-username-query}")
private String authoritiesQuery;

@Autowired
private MyAuthenticationHandler myAuthenticationHandler;




@Autowired
private Service service;


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


    List<UrlRole> viewPermissions = service.findAllUrlRole();
    System.out.println("Return from service class with size "+viewPermissions.size());
    ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry interceptUrlRegistry = http
            .authorizeRequests().antMatchers("/rest/**")
            .permitAll();
    interceptUrlRegistry.antMatchers("/login").access("hasRole('ROLE_ANONYMOUS')");

     interceptUrlRegistry.anyRequest().authenticated().accessDecisionManager(accessDecisionManager())
     .and()
     .formLogin()
     .loginPage("/login").successHandler(myAuthenticationHandler)
     .usernameParameter("username")
    .passwordParameter("password")
     .and()
 .logout()
     .permitAll()
     .and()
 .exceptionHandling()
.accessDeniedPage("/403");

}

@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
        .jdbcAuthentication().dataSource(dataSource)
        .usersByUsernameQuery(usersQuery)
        .authoritiesByUsernameQuery(authoritiesQuery);

}

@Override
public void configure(WebSecurity web) throws Exception {
    web
       .ignoring()
       .antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**", "/assets/**","/rest/findAllUrlRole","/error","/403","/404","/500");


}

@SuppressWarnings("unchecked")
@Bean
public AccessDecisionManager accessDecisionManager() {

    System.out.println("Arrive AccessDecisionManager");

    List<AccessDecisionVoter<? extends Object>> decisionVoters 
    = Arrays.asList(
            new WebExpressionVoter(),
            new RoleVoter(),
            new AuthenticatedVoter(),
            new MinuteBasedVoter());

    System.out.println("End of AccessDecisionManager: "+ decisionVoters);
    return new UnanimousBased(decisionVoters);
}

}

这是我的MinuteBasedVoter类:

@SuppressWarnings("rawtypes")
public class MinuteBasedVoter implements AccessDecisionVoter {


@Override
public int vote(
  Authentication authentication, Object object, Collection collection) {
    WebServiceTester a = new WebServiceTester();
    String username = authentication.getName(); //to get current user role
    String url = ((FilterInvocation) object).getRequestUrl(); // to get current url
    boolean NONanonymous = true;
    Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
    for (GrantedAuthority grantedAuthority : authorities) {
        if(grantedAuthority.getAuthority().equalsIgnoreCase("ROLE_ANONYMOUS")){
            NONanonymous = false;
        }
          }
    int vote = ACCESS_ABSTAIN;
    boolean NONexist = true;
    if(NONanonymous){
    List<Role> roles = new ArrayList<Role>();
    Role role = new Role();
    vote = ACCESS_DENIED;
    try{
    List<UrlRole> urlroles = a.findAllUrlRole(); // to get all url and its respective role
    // below is how i match the role of current user and the role that can access the current url
    for(int i = 0; i<urlroles.size();i++){

        if(url.startsWith(urlroles.get(i).getUrl())){
            NONexist = false;
            System.out.println("URL: "+url+" , Role: "+urlroles.get(i).getRole());  
            role.setRole(urlroles.get(i).getRole());
            roles.add(role);
            for (GrantedAuthority grantedAuthority : authorities) {
                if(grantedAuthority.getAuthority().equalsIgnoreCase(urlroles.get(i).getRole())){
                    vote = ACCESS_GRANTED;
                }
                  }

        }
    }
    }catch(Exception e){
        System.out.println("Error at MinuteBasedVoter: "+e);
    }
    if(NONexist){
        vote = ACCESS_GRANTED;
    }
    }

    return vote;
}

@Override
public boolean supports(ConfigAttribute attribute) {
    // TODO Auto-generated method stub
    return true;
}

@Override
public boolean supports(Class clazz) {
    // TODO Auto-generated method stub
    return true;
}
}

我从http://www.baeldung.com/spring-security-custom-voter得到了这个解决方案,但我自己扭曲了。

0 个答案:

没有答案