【微服务|Spring Security⑮】spring security自定义认证

Spring Security提供了非常好的认证扩展方法,比如:将用户信息存储到内存中,实际开发中用户信息通常在数据库,Spring Security可以实现从数据库读取用户信息,Spring security还支持多种授权方法。

4.3.1 自定义登录页面

Spring Security的默认配置没有明确设定一个登录页面的URL ,因此Spring Security会根据启用的功能自动生成一个登录页面URL ,并使用默认URL处理登录的提交内容,登录后跳转的到默认URL等等。尽管自动生成的登录页面很方便快速启动和运行,但大多数应用程序都希望定义自己的登录页面。

4.3.1.1 认证页面

将security-springmvc工程的login.jsp拷贝到security-springboot下,目录保持一致。

在这里插入代码片
4.3.1.2 配置认证页面

在WebConfig.java中配置认证页面地址:

//默认Url根路径剧阵专至Ij/login ,此url为spring security提供
@0verride
public void addViewControllers(ViewControllerRegistry registry) 
{
  registry.addViewController("/").setViewName("login-view")
    registry.addViewController("login-view").setViewName("login");
}
4.3.1.3 安全配置

在WebSecurityConfig中配置表单登录信息:


(1)允许表单登录 (2 )指定我们自己的登录页,spring security以重定向方式将路径转发到/login-view (3)指定登录处理的URL ,也就是用户名、密码表单提交的目的路径 (4)指定登录成功后的跳转URL (5 )我们必须允许所有用户访问我们的登录页(例如为验证的用户),这个formLogin() .permitAll()方法允许任意用户访问基于表单登录的所有的URL。

4.3.1.4 测试

当用户没有认证时访问系统的资源会重定向到login-view页面

在这里插入代码片

输入账号和密码,点击登录,报错

在这里插入代码片

问题解决:

spring security为防止CSRF ( Cross-site request forgery跨站请求伪造)的发生,限制了除了get以外的大多数方 法。

解决方法1:

屏蔽CSRF控制,即spring security不再限制CSRF。 配置 WebSecurityConfig

@0verride
protected void configure(HttpSecurity http) throws Exception 
{
   http.csrf().disable()//屏蔽CSRF控制,即 spring security 不再限制CSRF
}

解决办法2 :

在login.jsp页面添加一个token , spring security会验证token ,如果token合法则可以继续请求。 修改 login.jsp

<form action="login" method="post">
 <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>

4.3.2 连接数据库认证

前边的例子我们是将用户信息存储在内存中,实际项目中用户信息存储在数据库中。根据前边对认证流程研究,只需要重新定义UserDetailService即可实现根据用户账号查询数据库。

4.3.2.1 创建数据库

创建user_db数据库

CREATE DATABASE ‘user_db’ CHARACTER SET ‘utf8‘ COLLATE ‘utf8_general_ci’;

创建t_user 表

CREATE TABLE 't_user' (
 'id' bigint(20) NOT NULL COMMENT,用户id',
 'username' varchar(64) NOT NULL,
 'password' varchar(64) NOT NULL,
 'fullname' varchar(255) NOT NULL COMMENT,用户姓名',
 'mobile' varchar(ll) DEFAULT NULL COMMENT,手机号
 PRIMARY KEY ('id') USING BTREE
)ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
4.3.2.2 代码实现

1 )定义dataSource
在application.properties 配置

spring.datasource.url=jdbc:mysql://localhost:3306/user_db
spring.datasource.username=root
spring.datasource.password=mysql
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

2)添加依赖

<dependency>
 <groupld>org.springframework.boot</groupld>
 <artifactld>spring-boot-starter-test</artifactld>
 <scope>test</scope>
</dependency>
<dependency>
 <groupld>org.springframework.boot</groupld>
 <artifactld>spring-boot-starter-jdbc</artifactld>
</dependency>
<dependency>
 <groupld>mysql</groupld>
 <artifactld>mysql-connector-java</artifactld>
 <version>5.1.47</version>
</dependency>

3 )定义Dao

定义模型类型,在model包定义UserDto:

@Data
public class UserDto private String id;
 private String username;
 private String password;
 private String fullname;
 private String mobile;
}

在Dao包定义UserDao :

@Repository
public class UserDao {
 @Autowired
 ZJdbcTemplate jdbcTemplate;
 public UserDto getUserByUsername(String username){
  String sql =r,select id,username,password,funname from t_user where username = ?";
  List<UserDto> list = jdbcTemplate.query(sqlj new Object[Jlusername}^ new BeanPropertyRowMappero(UserDto. class));
  if(list == null && list.size() <= 0)(
   return null;
  }
  return list.get(0);
 }
}
4.3.2.3 定义 UserDetailService

在service包下定义SpringDatallserDetailsService :

@Service
public class SpringDatallserDetailsService implements UserDetailsService {
  @Autowired
  UserDao userDao;
  
  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
   //登录账号
   System.out. println();
   
   //根据账号去数据库查询...
   UserDto user = userDao.getUserByUsername(username);
   
   if(user == null){
    return null;
   }
   //这里暂时使用静态麴居
   UserDetails userDetails =User.withUsername(user.getFullname()).password(user.getPassword()).authorities("pl").build(); 
   return userDetails;
  }
}
4.3.2.3 测试

输入账号和密码请求认证,跟踪代码。

4.3.2.4 使用BCryptPasswordEncoder

按照我们前边讲的PasswordEncoder的使用方法,使用BCryptPasswordEncoder需要完成如下工作:

1、在安全配置类中定义BCryptPasswordEncoder

@Bean
public PasswordEncoder passwordEncoder() {
 return new BCryptPasswordEncoder();
}

2、UserDetails中的密码存储BCrypt格式

前边实现了从数据库查询用户信息,所以数据库中的密码应该存储BCrypt格式

package com.uncle.seciruty.springboot.util;

import org.springframework.security.crypto.bcrypt.BCrypt;

/**
 * @program: spring-boot-security
 * @description:
 * @author: 步尔斯特
 * @create: 2021-08-06 22:12
 */

public class BCryptUtil {
    public static void main(String[] args) {
        String hashpw = BCrypt.hashpw("456", BCrypt.gensalt());
        System.out.println(hashpw);

        boolean checkpw = BCrypt.checkpw("456","$2a$10$bcJXXryMCxXtkxRkG1UekOkOe0BqxiqOYKJzGni64jnyWAD15wmDy");
        System.out.println(checkpw);

        //123 -> $2a$10$8iHn2TEvyzkUgO2np9glzufe.wtRyjA5u3xfvs/D.9FCzm1XvCAGm
        //456 -> $2a$10$bcJXXryMCxXtkxRkG1UekOkOe0BqxiqOYKJzGni64jnyWAD15wmDy

    }
}

```**加粗样式**


原文始发于微信公众号(步尔斯特):【微服务|Spring Security⑮】spring security自定义认证

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/48009.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!