Security安全框架使用
什么都不用说了,直接看代码吧!!
pom.xml
导入依赖
<!-- security安全框架 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Security配置类
import com.yumbo.service.UserService;
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.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* @Author: GrainFull
* @Date: 2021/4/20 5:35
* @Description: Security配置类
*/
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public UserDetailsService getUserService() {
return new UserService();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(getUserService()).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/plugins/**", "/login", "/404").permitAll()// 无需认证
.antMatchers("/admin/**").hasAnyRole("ROLE_ADMIN") // 必须有ADMIN权限
.anyRequest().authenticated() // 所有请求都需要验证
.and()
.formLogin() // 使用默认的登录页面
.loginPage("/login")// 指定指定要的登录页面
.loginProcessingUrl("/doLogin")// 处理认证路径的请求
//认证成功后的跳转页面 默认是get方式提交 自定义成功页面post方式提交
//在 controller中处理时要注意
.defaultSuccessUrl("/index")
.failureForwardUrl("/404")
.and()
//开启cookie保存用户数据
.rememberMe()
//设置cookie有效期
.tokenValiditySeconds(60 * 60 * 24 * 7) //有效期一周
//设置cookie的私钥
// .key("")
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
.invalidateHttpSession(true)
.and()
.csrf().disable() //关闭跨域保护
.sessionManagement()
.maximumSessions(1);// 同一用户 只允许一个在线 自动踢出在线用户
}
}
登录认证类
UserSerice
@Service
public class UserService implements UserDetailsService {
@Autowired(required = false)
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 根据用户查询用户信息
//User user = userMapper.findByUsername(username); //查询数据库
User user = new User(1, username, "123456", "admin", "15535795261", "admin@163.com", "男", "上海");//注意:这里我就是用来测试的,实际应该从数据库中获取
if (user != null) {
// 根据用户查询用户对应权限
Collection<GrantedAuthority> authorities = new ArrayList<>();
/* //查询登录用户所拥有的角色
List<Role> list = RoleMapper.findByUserId(userId);
for (Role role : list) {
GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_"+role.getRoleName());
authorities.add(authority);
}
*/
//创建一个授权对象
GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_ADMIN"); //注意:这里我就是用来测试的,实际应该从数据库中获取
authorities.add(authority);
return new org.springframework.security.core.userdetails.User(
user.getUsername(),
// 因为数据库是明文,所以这里需加密密码
passwordEncoder.encode(user.getPassword()),
authorities);
}
return null;
}
}
控制层
LoginController
@Controller
public class LoginController extends BaseController {
@Autowired(required = false)
private UserService userService;
/**
* 登录视图
*
* @return
*/
@RequestMapping(value = "login")
public String login() {
return "login";
}
/**
* 主页视图
*
* @return
*/
@RequestMapping(value = "index")
public String index() {
return "index";
}
/**
* 404视图
*
* @return
*/
@RequestMapping(value = "404")
public String error() {
return "404";
}
BaseController
import org.springframework.web.bind.annotation.ModelAttribute;
import javax.servlet.http.HttpServletRequest;
/**
* @Author: GrainFull
* @Date: 2021/4/20 16:11
* @Description:
*/
public class BaseController {
@ModelAttribute
public void preHandler(HttpServletRequest request) {
request.setAttribute("ctx", request.getContextPath());
}
}
登录页面
login.ftl
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>云博-登录</title>
<#include "common.ftl"/>
<link rel="stylesheet" href="${ctx}/plugins/css/login.css" media="all">
<script type="text/javascript" src="${ctx}/plugins/js/login.js" charset="UTF-8"></script>
</head>
<body class="poster">
<form class="form-horizontal login-container" id="loginForm" role="form" action="${ctx}/doLogin" method="post">
<h2 class="login_title">云博-登录</h2>
<div class="form-group">
<label for="username" class="control-label"></label>
<div class="col-sm-12">
<input type="text" class="form-control" name="username" id="username" placeholder="请输入账号">
</div>
</div>
<div class="form-group">
<label for="password" class="control-label"></label>
<div class="col-sm-12">
<input type="password" class="form-control" name="password" id="password" placeholder="请输入密码">
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<button type="submit" class="btn btn-default col-sm-12 loginSubmit">登录</button>
</div>
</div>
</form>
</body>
</html>
login.css
/**
* @Author: GrainFull
* @Date: 2021/4/20 16:07
* @Description:
*/
.login-container {
border-radius: 15px;
background-clip: padding-box;
margin: 170px auto;
width: 350px;
padding: 35px 35px 35px 35px;
background-color: transparent;
border: 1px solid #eaeaea;
/*阴影设置*/
box-shadow: 0 0 25px #cac6c6;
background-color: #FFFFFF;
}
.login_title {
margin: 0px auto 40px auto;
text-align: center;
color: #505458;
}
.loginSubmit {
width: 100%;
background: #505458;
border: none;
color: #FFFFFF;
}
.poster {
height: 100%;
width: 100%;
/*background: #009688;*/
}
body {
margin: 0;
}
login.js
/**
* @Author: GrainFull
* @Date: 2021/4/20 16:14
* @Description:
*/
charset = "UTF-8"
$(function () {
$("#loginForm").on("submit", function () {
var params = $(this).serializeArray();
var requestUrl = $(this).attr("action");
$.ajax({
// url: ctx + "/doLogin",
url: requestUrl,
type: "post",
data: params,
cache: false,//false是不缓存,true为缓存
async: true, //true为异步,false为同步
beforeSend: function () {
//请求前
console.log("准备登录请求了..")
},
success: function (res) {
console.log("登陆成功");
// if (res.code == 200) {
// console.log("登陆成功");
// window.location.href = ctx+"/index";
// }
},
complete: function () {
//请求结束时
console.log("登录请求结束了..")
alert("登录请求结束了..")
},
error: function () {
//请求失败时
console.log("登录失败..")
}
});
});
});
common.ftl
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="${ctx}/plugins/images/favicon.ico">
<!-- 引入 Bootstrap -->
<link href="${ctx}/plugins/bootstrap-3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="${ctx}/plugins/bootstrap-3.3.7/css/bootstrap-theme.min.css" rel="stylesheet">
<!-- HTML5 Shiv 和 Respond.js 用于让 IE8 支持 HTML5元素和媒体查询 -->
<!-- 注意: 如果通过 file:// 引入 Respond.js 文件,则该文件无法起效果 -->
<!--[if lt IE 9]>
<script src="${ctx}/plugins/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="${ctx}/plugins/libs/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<!-- jQuery (Bootstrap 的 JavaScript 插件需要引入 jQuery) -->
<script src="${ctx}/plugins/jquery/jquery.js"></script>
<!-- 包括所有已编译的插件 -->
<script src="${ctx}/plugins/bootstrap-3.3.7/js/bootstrap.min.js"></script>
<#--<script type="text/javascript">-->
<#-- var ctx = "${ctx}";-->
<#--</script>-->
index.ftl
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>云博-主页</title>
<#include "common.ftl"/>
</head>
<body>
<h3><i>欢迎使用云博管理系统</i></h3>
</body>
</html>
application.yml
server:
port: 8080
servlet:
context-path: /yumbo
tomcat:
uri-encoding: UTF-8
max-threads: 1000
min-spare-threads: 30
spring:
## freemarker
freemarker:
suffix: .ftl
content-type: text/html
charset: UTF-8
template-loader-path: classpath:/views/
settings:
classic_compatible: true
## 启用热部署
devtools:
restart:
enabled: true
additional-paths: src/main/java
简单的security使用,欢迎大家参考借鉴
shiro框架:https://blog.csdn.net/qq_45742386/article/details/115983887