📜  Spring Security - 自定义登录(1)

📅  最后修改于: 2023-12-03 14:47:33.889000             🧑  作者: Mango

Spring Security - 自定义登录

简介

Spring Security是一个功能强大的安全框架,它为Java应用提供了身份验证和授权机制。Spring Security的默认登录页面和逻辑满足了通常的要求,但是在实际项目中,我们经常需要自定义登录页面和登录逻辑,这就需要使用Spring Security的自定义登录功能了。

本文主要介绍如何使用Spring Security自定义登录,并提供一个简单的示例。

实现步骤
添加依赖

首先需要在项目中添加Spring Security的依赖,可以通过以下Maven坐标添加到项目中:

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>5.5.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>5.5.0</version>
</dependency>
配置Spring Security

在Spring配置文件(如applicationContext.xml)中配置Spring Security,包括密码加密算法、用户认证、认证成功后的处理等:

<security:http>
    <security:intercept-url pattern="/admin/**" access="hasRole('ADMIN')" />
    <security:form-login login-page="/login" default-target-url="/home" authentication-failure-url="/login?error=true" />
    <security:logout logout-success-url="/logout" />
</security:http>
<security:authentication-manager>
    <security:authentication-provider>
        <security:user-service>
            <security:user name="admin" password="{noop}admin" authorities="ROLE_ADMIN" />
            <security:user name="user" password="{noop}user" authorities="ROLE_USER" />
        </security:user-service>
    </security:authentication-provider>
</security:authentication-manager>

以上配置中,"/admin/**"是受保护的资源,只有拥有ROLE_ADMIN角色的用户才能访问;"/login"是自定义的登录页面;"/home"是登录成功后默认跳转的页面;"/logout"是退出登录的处理页面。

实现自定义登录页面

在项目中创建一个名为"login.jsp"的页面,页面中包含一个登录表单,表单的提交地址为"/login":

<form action="/login" method="post">
    <label>Username:</label>
    <input type="text" name="username" />
    <br />
    <label>Password:</label>
    <input type="password" name="password" />
    <br />
    <input type="submit" value="Login" />
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
实现登录成功/失败的处理逻辑

在Spring配置文件中配置登录成功后和登录失败后的处理逻辑:

<bean id="simpleUrlAuthenticationSuccessHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
    <property name="defaultTargetUrl" value="/home" />
</bean>

<bean id="simpleUrlAuthenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
    <property name="defaultFailureUrl" value="/login?error=true" />
</bean>

<security:http>
    ...
    <security:form-login login-page="/login" authentication-success-handler-ref="simpleUrlAuthenticationSuccessHandler" authentication-failure-handler-ref="simpleUrlAuthenticationFailureHandler" />
    ...
</security:http>

以上配置中,simpleUrlAuthenticationSuccessHandler是登录成功后的处理类,defaultTargetUrl是登录成功后默认跳转的页面;simpleUrlAuthenticationFailureHandler是登录失败后的处理类,defaultFailureUrl是登录失败后跳转到的页面。

完整示例代码

WebSecurityConfig.java

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("admin").password("{noop}admin").roles("ADMIN")
            .and()
            .withUser("user").password("{noop}user").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**").access("hasRole('ADMIN')")
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .successHandler(new SimpleUrlAuthenticationSuccessHandler("/home"))
                .failureHandler(new SimpleUrlAuthenticationFailureHandler("/login?error=true"))
                .permitAll()
                .and()
            .logout()
                .logoutSuccessUrl("/logout")
                .permitAll()
                .and()
            .csrf().disable();
    }

}

login.jsp

<form action="/login" method="post">
    <label>Username:</label>
    <input type="text" name="username" />
    <br />
    <label>Password:</label>
    <input type="password" name="password" />
    <br />
    <input type="submit" value="Login" />
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>

HomeController.java

@Controller
public class HomeController {

    @RequestMapping(value = "/home", method = RequestMethod.GET)
    public String homePage(ModelMap model) {
        model.addAttribute("message", "Welcome to home page");
        return "home";
    }

}
总结

Spring Security自定义登录是一项非常实用的功能,在实际项目中经常用到。本文介绍了Spring Security自定义登录的实现步骤,并提供了示例代码,希望对读者能有所帮助。