Spring Security入门教程 通俗易懂 超详细
Spring Security的简单使用
推荐 Java 常见面试题
简介
- SSM 整合 Security 是比较麻烦的,虽然Security的功能比 Shiro 强大,相反却没有Shiro的使用量多
- SpringBoot出现后简化了Spring系列的配置文件,因此SpringSecurity的使用逐渐增加
一、创建项目
查看代码
在 SpringBoot 中直接引入 Spring Security 依赖即可
创建项目的启动类
创建 SecurityController 类
- 启动后访问
localhost:8080/hello
- 会自动跳到
localhost:8080/login
- 需要登录后才能访问
/hello
二、用户名配置
查看代码
- 默认情况下用户名是
user
,而密码会在项目启动时控制台
打印出一串随机字符串
,这就是密码.每次启动项目,密码都不一样
- 对登录的用户名/密码进行配置,有三种不同的方式
- 在
application
配置文件中声明- 在
java
代码配置在内存里- 通过获取
数据库
第一种方式
application.yml
文件中
第二种方式 创建一个
SecurityConfig
配置类,继承WebSecurityConfigurerAdapter
第三种方法没有进行演示,就是在数据库中取出
username
和password
配置到内存中
三、忽略拦截
查看代码
在配置类中重写
configure(WebSecurity web)
方法,然后直接访问即可
pom.xml文件
返回阅读
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--Web项目 需引入web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
启动类文件
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author https://www.cnblogs.com/beixuan/
*/
@SpringBootApplication
public class SecurityApplication {
public static void main(String[] args) {
SpringApplication.run(SecurityApplication.class, args);
}
}
SecurityController 文件
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author https://www.cnblogs.com/beixuan/
*/
@RestController
public class SecurityController {
/**
* 不用登录就可访问
* @return
*/
@RequestMapping("/hi")
public String sayHi(){
return "Hi bro!";
}
@RequestMapping("/hello")
public String sayHello(){
return "Hello bro!";
}
}
application.yml 配置文件
返回阅读
spring:
security:
user:
name: beixuan
password: beixuan
SecurityConfig Java配置文件
此方法配置用户与配置
yml
文件效果一致
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* @author https://www.cnblogs.com/beixuan/
*/
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
//Spring Security5之后 官方需要密码强制加密,如不想加密可创建一个过期的 PasswordEncoder 的实例 NoOpPasswordEncoder,但不安全
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
String password = bCryptPasswordEncoder.encode("beixuan");
//添加一个用户[beixuan] 角色为[admin] 密码是[beixuan加密后的密钥]
auth.inMemoryAuthentication()
.withUser("beixuan")
.roles("admin")
.password(password);
}
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
- 具体的登录配置 下面代码借鉴于 江南一点雨 随笔的代码,有兴趣可以看看
VerifyCodeFilter
一次性验证码,可以查看资料了解其使用方法,这里不再叙述
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
VerifyCodeFilter verifyCodeFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(verifyCodeFilter, UsernamePasswordAuthenticationFilter.class);
http
.authorizeRequests()//开启登录配置
.antMatchers("/hello").hasRole("admin")//表示访问 /hello 这个接口,需要具备 admin 这个角色
.anyRequest().authenticated()//表示剩余的其他接口,登录之后就能访问
.and()
.formLogin()
//定义登录页面,未登录时,访问一个需要登录之后才能访问的接口,会自动跳转到该页面
.loginPage("/login_p")
//登录处理接口
.loginProcessingUrl("/doLogin")
//定义登录时,用户名的 key,默认为 username
.usernameParameter("uname")
//定义登录时,用户密码的 key,默认为 password
.passwordParameter("passwd")
//登录成功的处理器
.successHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
out.write("success");
out.flush();
}
})
.failureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException exception) throws IOException, ServletException {
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
out.write("fail");
out.flush();
}
})
.permitAll()//和表单登录相关的接口统统都直接通过
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(new LogoutSuccessHandler() {
@Override
public void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
out.write("logout success");
out.flush();
}
})
.permitAll()
.and()
.httpBasic()
.and()
.csrf().disable();
}
忽略拦截分两步
返回阅读
增加访问路径
/hi
/**
* 不用登录就可访问
* @return
*/
@RequestMapping("/hi")
public String sayHi(){
return "Hi bro!";
}
增加配置代码
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/hi");
}
即可不用登录访问
/hi
路径
END
本文就先说到这里,有问题欢迎留言讨论