spring启动安全性自定义登录页到不同的url“/”不工作

yzxexxkh  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(378)

我刚刚查看了许多关于自定义登录页的示例,每个示例都使用相同的“/login”路径。经过这么多的挫折,我终于得到了登录与默认工作。
我希望登录表单在“/”处呈现,而不是登录。
一旦认证,我希望它回家。
我假设帖子还是默认的“/登录”?
我在post表单“/”(与get表单路径相同)和“/login”上都试过了
现在,当我尝试登录时,它会不断地将我重定向回与表单相同的“/”。
下面是基本的api逻辑:默认登录页面应该是“/”,表单发布到“/login”,登录后的成功url是“/home”,“/home”和“/mama”是受保护的路由。注销后,应重定向到“/”
我无法通过该应用程序,不知道是否有任何遗漏,它一直显示相同的形式登录,如果我没有通过,即使密码显然是好的
以下是WebConfigureAdapter文件服务器中说明的路由:

@Configuration
@EnableWebSecurity
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(userDetailsService);

        /*auth.inMemoryAuthentication()
                .withUser("appuser").password("1234").roles("HEAD")
                .and()
                .withUser("Mama").password("Mama").roles("MAMA");*/

    }

    @Override
    /*
    * Now we have learnt the basics of Spring Security & Authrization method is completed.
    * Lets fix Authentication first!
    * Got it to work with hasAuthority & hasAnyAuthority but not with roles, not sure why, but it works atm
    *
    * */
    protected void configure(HttpSecurity http) throws Exception {
        //Disabled for development
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/mama").hasAuthority("MAMA")
                .antMatchers("/home").hasAnyAuthority("HEAD", "MAMA")
                .anyRequest().authenticated()
                .and()
                .formLogin()
                    .loginPage("/").permitAll()
                    .defaultSuccessUrl("/home")
                    .usernameParameter("username")
                    .passwordParameter("password")
                .and()
                .logout()
                    .logoutSuccessUrl("/");
    }

    @Bean
    /*
    * Returning no op password encoder for now, as we are not encoding passwords as no registration
    * implemented for Prototype. We would need to add the users from a separate service. W
    *
    * */
    public PasswordEncoder getPasswordEncoder(){
        return NoOpPasswordEncoder.getInstance();
    }

}

//LoginApi:
@RestController
public class LoginApi {

    @RequestMapping("/")
    public String index(){
        return "<form method='POST' action='/login'>" +
                "<div>" +
                "<input type='text' name='username' placeholder='Username: ' />" +
                "</div>" +
                "<div>" +
                "<input type='password' name='password' placeholder='Password: ' />" +
                "</div>" +
                "<div>" +
                "<input type='submit' name='submit' value='Login' />" +
                "</div>" +
                "</form>";
    }

    @RequestMapping("/home")
    public String home(){
        return "Welcome to Home!";
    }

    /*
    * This method can be deleted in the end
    * */
    @RequestMapping("/mama")
    public String roleTest(){
        return "This end point is only for Mama!";
    }

}

对于这个测试,我没有使用数据库,但是我有一个userprincipal和userdetailsservice的工作实现,它在默认的登录设置上工作得非常好。如果需要的话,很乐意分享代码。但在这一点上,我看不出哪里会出错。
如果有人想查看userdetails服务和userdetails代码,也包括:

@Service
public class EmployeeDetailsService implements UserDetailsService {

    @Override
    /*
    * First, we are testing the Employee details service, independent of the Database, just to make sure we have this part working,
    * For the purpose of these prototypes, we wont use password encoder because we are not registering,
    *
    * */
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        if (!username.equals("Mama")){
            throw new UsernameNotFoundException("You got the wrong Username, should be mama");
        }

        Employee employee = new Employee();
        Role role = new Role();
        role.setName("HEAD");
        employee
                .setUsername(username)
                .setPassword("1234")
                .setRole(role);

        return new EmployeePrincipal(employee);

    }
}

public class EmployeePrincipal implements UserDetails {

    private Employee employee;

    public EmployeePrincipal(Employee employee){
        this.employee = employee;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
        authorities.add(new SimpleGrantedAuthority(employee.getRole().getName()));
        return  authorities;
    }

    @Override
    public String getPassword() {
        return employee.getPassword();
    }

    @Override
    public String getUsername() {
        return employee.getUsername();
    }

    /*
    * Methods below are the rubbish methods, we keep as true for now
    *
    * */
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

看到图片附从网络,我不明白发生了什么?post请求将302重定向回“/”,状态代码为200?
无论凭证是对是错,都会发生这种情况

如有任何建议,将不胜感激

neekobn8

neekobn81#

csrf需要用一个定制的表单来实现,所以对于测试和开发人员来说,最好禁用csrf

protected void configure(HttpSecurity http) throws Exception {
        //Disabled for development
        http.authorizeRequests()
                .antMatchers("/mama").hasAuthority("MAMA")
                .antMatchers("/home").hasAnyAuthority("HEAD", "MAMA")
                .anyRequest().authenticated()
                .and()
                .csrf().disable()
                .formLogin()
                    .loginPage("/").permitAll()
                    .loginProcessingUrl("/login")
                    .defaultSuccessUrl("/home")
                .and()
                .logout()
                    .logoutSuccessUrl("/");
    }

相关问题