首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Spring表单登录,多个角色与表单问题

Spring表单登录,多个角色与表单问题
EN

Stack Overflow用户
提问于 2017-12-06 03:15:11
回答 1查看 915关注 0票数 0

好的,我有我的登录页面在本地主机/登录在那里,我有两个表单,具有相同的动作,即/login (目前)。我正在努力完成这个场景:

用户在登录页面上,他可以在两个表单之间进行选择。提供一个表单,它将把他重定向到/employees/home。请记住,具有管理角色的用户也可以登录到/employees/home

应用程序有两个角色管理和EMP。

我希望web应用程序能够为每个用户正确地授予权限,并将其重定向到需要的位置。我可以用一个角色来完成这个任务,但是一旦我加入了另一个角色,应用程序就会开始失去它。这是我的密码:

代码语言:javascript
运行
复制
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;

@Autowired
private DataSource dataSource;

@Value("${spring.queries.users-query}")
private String usersQuery;

@Value("${spring.queries.roles-query}")
private String rolesQuery;

@Override
protected void configure(AuthenticationManagerBuilder auth)
        throws Exception {
    auth.
        jdbcAuthentication()
            .usersByUsernameQuery(usersQuery)
            .authoritiesByUsernameQuery(rolesQuery)
            .dataSource(dataSource)
            .passwordEncoder(bCryptPasswordEncoder);
}


protected void configure(HttpSecurity http) throws Exception {
    http.
    authorizeRequests()
        .antMatchers("/").permitAll()
        .antMatchers("/login").permitAll()
        .antMatchers("/admin/**").hasAuthority("ADMIN").anyRequest()
        .authenticated().and().formLogin()
        .loginPage("/login/administrator").failureUrl("/login?error=true")
        .defaultSuccessUrl("/admin/home")
        .usernameParameter("email")
        .passwordParameter("password")
        .and().logout()
        .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
        .logoutSuccessUrl("/").and().exceptionHandling()
        .accessDeniedPage("/access-denied")
        .and()
        .authorizeRequests()
        .antMatchers("/employee/**").hasAuthority("EMP")
        .anyRequest().authenticated().and().formLogin()
        .loginPage("/login").failureUrl("/login?error=true")
        .defaultSuccessUrl("/employee/home")
        .usernameParameter("email")
        .passwordParameter("password")
        .and().logout()
        .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
        .logoutSuccessUrl("/").and().exceptionHandling()
        .accessDeniedPage("/access-denied")
        ;
/*  http.
    authorizeRequests()
        .antMatchers("/").permitAll()
        .antMatchers("/login").permitAll()
        .antMatchers("/admin/**").hasAuthority("ADMIN").anyRequest()
        .authenticated().and().csrf().disable().formLogin()
        .loginPage("/login").failureUrl("/login?error=true")
        .defaultSuccessUrl("/admin/home")
        .usernameParameter("email")
        .passwordParameter("password")
        .and().logout()
        .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
        .logoutSuccessUrl("/").and().exceptionHandling()
        .accessDeniedPage("/access-denied");*/
}

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

查询

代码语言:javascript
运行
复制
spring.queries.users-query=select email, password, active from user where email=?
spring.queries.roles-query=select u.email, r.role from user u inner join user_role ur on(u.user_id=ur.user_id) inner join role r on(ur.role_id=r.role_id) where u.email=?

主登录控制器

代码语言:javascript
运行
复制
@Controller
public class LoginController {

    @RequestMapping(value={"/","/login"}, method = RequestMethod.GET)
    public ModelAndView login(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("login");
        return modelAndView;
    }

存储库和服务工作,他们是用一个单一的角色进行测试。我认为这是SecurityConfiguration类的问题所在。注*我尝试过用不同的顺序创建几个配置类,但这也不起作用。

任何帮助都将不胜感激!!谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-07 16:20:43

经过一些深入研究后,正如Sankar所说的那样,设法解决了这个问题,并使用了自定义的成功处理程序类。

代码语言:javascript
运行
复制
public class CustomSuccessHandler
  implements AuthenticationSuccessHandler {
....
protected String determineTargetUrl(Authentication authentication) {
        boolean isEmp= false;
        boolean isAdmin = false;
        Collection<? extends GrantedAuthority> authorities
         = authentication.getAuthorities();
        for (GrantedAuthority grantedAuthority : authorities) {
            if (grantedAuthority.getAuthority().equals("EMPLOYEE")) {
                isUser = true;
                break;
            } else if (grantedAuthority.getAuthority().equals("ADMIN")) {
                isAdmin = true;
                break;
            }
        }

        if (isEmp) {
            return "/employee/home";
        } else if (isAdmin) {
            return "/admin/home";
        } else {
            throw new IllegalStateException();
        }
    }
....
}

但最后,决定放弃逻辑,切换到一个单一的日志形式,这将导致登陆页面,从那里用户可以选择去哪里。

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

        http.
        authorizeRequests()
            .antMatchers("/").permitAll()
            .antMatchers("/rest/**").permitAll()
            .antMatchers("/login").permitAll()
            .antMatchers("/landing").hasAnyAuthority("ADMIN","EMPLOYEE")
            .antMatchers("/admin/**").hasAuthority("ADMIN")
            .antMatchers("/employee/**").hasAuthority("EMPLOYEE")
            .anyRequest()
            .authenticated().and()
            .formLogin()
            .loginPage("/login").failureUrl("/login?error=true")
            .defaultSuccessUrl("/landing")
            .usernameParameter("email")
            .passwordParameter("password")
            .and().logout()
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/login").and().exceptionHandling()
            .accessDeniedPage("/access-denied");

    }

根据用户的角色链接到/employee/home或/admin/home的链接是否禁用。

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

https://stackoverflow.com/questions/47666233

复制
相关文章

相似问题

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