SpringSecurity:认证和自定义登陆界面

目录

配置

解决中文乱码问题

认证

直接认证

使用数据库认证

自定义登录界面

替换默认的登陆界面

关闭csrf防护


配置

配置初始化器

public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
    //不用重写任何内容
  	//这里实际上会自动注册一个Filter,SpringSecurity底层就是依靠N个过滤器实现的
}

创建一个配置类用于配置 SpringSecurity

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
		//继承WebSecurityConfigurerAdapter,之后会进行配置
}

在初始化器中把该配置类添加进去

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class[]{RootConfiguration.class, SecurityConfiguration.class};
}

解决中文乱码问题

在初始化器添加,要在进入过滤链之前设置编码方式

public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
    @Override
    protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
        servletContext.addFilter("CharacterEncodingFilter", new CharacterEncodingFilter("utf-8", true))
                .addMappingForUrlPatterns(null, false, "/*");
        //super.beforeSpringSecurityFilterChain(servletContext);
    }
}

认证

要实现登录功能,就需要用户认证

直接认证

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();  
//这里使用SpringSecurity提供的BCryptPasswordEncoder
    auth
            .inMemoryAuthentication() //直接验证方式
            .passwordEncoder(encoder) //密码加密器
            .withUser("test")   //用户名
            .password(encoder.encode("123456"))   //这里需要填写加密后的密码
            .roles("user");   //用户的角色
}

SpringSecurity 的密码校验并不是直接使用原文进行比较,而是使用加密算法将密码进行加密,而且这个过程是不可逆的,然后将用户提供的密码以同样的方式加密后与密文进行比较,保存也是密文,所以即使数据库被窃取了也无法得知密码是多少,很好地保证了用户信息的安全性。

使用数据库认证

需要创建一个 Service 来实现 接口UserDetailsService,它支持我们自己返回一个 UserDetails 对象,我们只需直接返回一个包含数据库中的用户名、密码等信息的 UserDetails 即可,SpringSecurity 会自动进行比对,在配置类中进行扫描并将其注册为 Bean

@Service
public class UserAuthService implements UserDetailsService {
    @Resource
    UserMapper mapper;
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        String password = mapper.getPasswordByUsername(s);  //从数据库根据用户名获取密码
        if(password == null)
            throw new UsernameNotFoundException("登录失败,用户名或密码错误!");
        return User   //这里需要返回UserDetails,SpringSecurity会根据给定的信息进行比对
                .withUsername(s)
                .password(password)   //直接从数据库取的密码
                .roles("user")   //用户角色
                .build();
    }
}

最后再修改一下 Security 配置类

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
      .userDetailsService(service)   //使用自定义的Service实现类进行验证
      .passwordEncoder(new BCryptPasswordEncoder());   //依然使用BCryptPasswordEncoder
}

自定义登录界面

替换默认的登陆界面

首先来看一下Spring Security的自定义界面,包含了一个重要的东西

    <input

      name="_csrf"

      type="hidden"

      value="83421936-b84b-44e3-be47-58bb2c14571a"

    />

他是隐藏的,为了防止 CSRF 攻击而存在的。

从 Spring Security 4.0 开始,默认情况下会启用 CSRF 保护,以防止 CSRF 攻击应用程序,Spring Security CSRF 会针对 PATCH,POST,PUT 和 DELETE 方法的请求(不仅仅只是登陆请求,这里指的是任何请求路径)进行防护。在不带_csrf的情况下,页面中只要发起了 PATCH,POST,PUT 和 DELETE 请求一定会被拒绝,并返回403错误

需要在请求的时候加入 csrfToken ,也就是"83421936-b84b-44e3-be47-58bb2c14571a",正是 csrfToken,如果提交的是表单类型的数据,那么表单中必须包含此 Token 字符串,键名称为"\_csrf";如果是 JSON 数据格式发送的,那么就需要在请求头中包含此 Token 字符串。

如果用的是Thymeleaf视图解析器,可以加一个这样的输入框

<input

  type="text"

  th:name="${_csrf.getParameterName()}"

  th:value="${_csrf.token}"

  hidden

/>

Token 的键名称和 Token 字符串可以通过 Thymeleaf 从 Model 中获取,SpringSecurity 会自动将 Token 信息添加到 Model 中

然后就可以配置自己的登陆界面了

先重写Security 配置类中的另一个configure方法

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()   //首先需要配置哪些请求会被拦截,哪些请求必须具有什么角色才能访问
            .antMatchers("/static/**").permitAll()    //静态资源,使用permitAll来运行任何人访问(注意一定要放在前面)
            .antMatchers("/**").hasRole("user")     //所有请求必须登陆并且是user角色才可以访问(不包含上面的静态资源)
}

配置拦截规则,也就是当用户未登录时,哪些路径可以访问,哪些路径不可以访问,如果不可以访问,那么会被自动重定向到登陆页面。

接着需要配置表单登陆和登录页面

.formLogin()       //配置Form表单登陆
.loginPage("/login")       //登陆页面地址(GET)
.loginProcessingUrl("/doLogin")    //form表单提交地址(POST)
.defaultSuccessUrl("/index")    //登陆成功后跳转的页面,也可以通过Handler实现高度自定义
.permitAll()    //登陆页面也需要允许所有人访问

登陆页面需要我们自己去编写 Controller 来实现,登陆请求提交处理由 SpringSecurity 提供,只需要写路径就可以了。

@RequestMapping("/login")
public String login(){
    return "login";
}

再需要配置一下退出登录操作

.and()
.logout()
.logoutUrl("/logout")    //退出登陆的请求地址
.logoutSuccessUrl("/login");    //退出后重定向的地址

注意这里的退出登陆请求也必须是 POST 请求方式(因为开启了 CSFR 防护,需要添加 Token),否则无法访问

<body>
    <form action="logout" method="post">
        <input type="text" th:name="${_csrf.getParameterName()}" th:value="${_csrf.token}" hidden>
        <button>退出登陆</button>
    </form>
</body>

关闭csrf防护

直接在配置类中配置

.and()

.csrf().disable();

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Security中,可以通过配置来自定义登录页面。需要进行以下几个步骤: 1. 创建自定义登录页面。可以在项目中创建一个JSP或HTML文件,用于显示登录表单。 2. 在Spring Security的配置文件中指定自定义登录页面。可以使用`<security:form-login>`元素来配置登录页面的路径,例如:`<security:form-login login-page="/login.jsp" />`。其中,`login-page`属性指定了登录页面的路径。 3. 确保自定义登录页面可以被匿名访问。可以使用`<security:intercept-url>`元素来配置URL的访问权限,例如:`<security:intercept-url pattern="/login.jsp" access="permitAll" />`。其中,`pattern`属性指定了匹配的URL路径,`access`属性指定了访问该URL的权限。 通过以上配置,您可以实现Spring Security自定义登录界面。请注意,在配置文件中的其他部分可能还有其他相关配置,比如配置认证信息、配置退出登录等。详细配置可以参考引用和引用中的示例代码和解释。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [SpringSecurity实现自定义登录界面](https://blog.csdn.net/qq_38526573/article/details/103402060)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值