说明
不知道说啥,就是简单的功能
创建项目添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
这时候项目启动的时候就会随机生成用户名密码,并且访问URL的时候会跳转默认登陆页面
基于内存的认证
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Resource
VerificationCodeFilter verificationCodeFilter;
@Bean
PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication() // 自定义内存中的帐号密码
.withUser("username")
.password("password")
.roles("admin"); // 定义账号的角色
}
@Override
public void configure(WebSecurity web) throws Exception {
// 定义一些资源相关的URL不用被拦截
web.ignoring().antMatchers("/css/**", "/js/**", "/index.html", "/images/**", "/fonts/**", "/favicon.ico", "/verifyCode");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// 在账号密码验证之前验证验证码
http.addFilterBefore(verificationCodeFilter, UsernamePasswordAuthenticationFilter.class);
// 设置请求鉴定
http.authorizeRequests()
.antMatchers("/backstage/**").hasRole("admin") // 设置需要拦截的请求
.and()
.formLogin()
.loginPage("/backstage/login") // 设置默认登陆页面
.loginProcessingUrl("/backstage/doLogin") // 设置登录页面表单的post请求url
.defaultSuccessUrl("/backstage/") // 设置登陆成功后默认跳转url
.permitAll()
.and().csrf().disable(); // 关闭csrf
}
}
添加验证码依赖
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>kaptcha</artifactId>
<version>0.0.9</version>
</dependency>
创建验证码过滤器
@Component
public class VerificationCodeFilter extends GenericFilter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
if (HttpMethod.POST.name().equals(req.getMethod()) && "/backstage/doLogin".equals(req.getServletPath())) {
String code = req.getParameter("captcha");
String verifyCode = (String) req.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
if (code == null || StringUtils.isEmpty(code) || !code.toLowerCase().equals(verifyCode.toLowerCase())) {
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
out.write(new ObjectMapper().writeValueAsString(HttpResult.error("ErrorVerifyCode")));
out.flush();
out.close();
} else {
filterChain.doFilter(req, resp);
}
} else {
filterChain.doFilter(req, resp);
}
}
@Override
public void destroy() {
}
}
HTTP结果封装
public class HttpResult {
private int code = 200;
private String msg;
private Object data;
public static HttpResult error() {
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
}
public static HttpResult error(String msg) {
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
}
public static HttpResult error(int code, String msg) {
HttpResult r = new HttpResult();
r.setCode(code);
r.setMsg(msg);
return r;
}
public static HttpResult ok(String msg) {
HttpResult r = new HttpResult();
r.setMsg(msg);
return r;
}
public static HttpResult ok(Object data) {
HttpResult r = new HttpResult();
r.setData(data);
return r;
}
public static HttpResult ok() {
return new HttpResult();
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
验证码生成接口
@RestController("/backstage")
public class SysLoginController {
@Autowired
private Producer producer;
// @Autowired
// private SysUserService sysUserService;
// @Autowired
// private AuthenticationManager authenticationManager;
@GetMapping("/captcha.jpg")
public void captcha(HttpServletResponse response, HttpServletRequest request) throws ServletException, IOException {
response.setHeader("Cache-Control", "no-store, no-cache");
response.setContentType("image/jpeg");
// 生成文字验证码
String text = producer.createText();
// 生成图片验证码
BufferedImage image = producer.createImage(text);
// 保存到验证码到 session
request.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY, text);
ServletOutputStream out = response.getOutputStream();
ImageIO.write(image, "jpg", out);
IOUtils.closeQuietly(out);
}
}
登录页面
<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<!-- Standard Meta -->
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<!-- Site Properties -->
<title>Login Example - Semantic</title>
<link rel="stylesheet" href="../../static/lib/editormd/css/editormd.min.css"
th:href="@{/lib/editormd/css/editormd.min.css}">
<link rel="stylesheet" href="../../static/css/icon.min.css" th:href="@{/css/icon.min.css}">
<link rel="stylesheet" href="../../static/css/semantic.min.css" th:href="@{/css/semantic.min.css}">
<link rel="stylesheet" href="../../static/css/typo.css" th:href="@{/css/typo.css}">
<link rel="stylesheet" href="../../static/css/animate.css" th:href="@{/css/animate.css}">
<link rel="stylesheet" href="../../static/lib/prism/prism.css" th:href="@{/lib/prism/prism.css}">
<link rel="stylesheet" href="../../static/lib/tocbot/tocbot.css" th:href="@{/lib/tocbot/tocbot.css}">
<link rel="stylesheet" href="../../static/css/me.css" th:href="@{/css/me.css}">
<link rel="stylesheet" href="../../static/css/blog.css" th:href="@{/css/blog.css}">
<link rel="stylesheet" href="../../static/css/common.css" th:href="@{/css/common.css}">
<link rel="stylesheet" href="../../static/css/action.css" th:href="@{/css/action.css}">
<link rel="stylesheet" type="text/css" href="../../static/css/font-awesome.min.css"
th:href="@{/css/font-awesome.min.css}"/>
<link rel="stylesheet" href="../../static/css/color.css" th:href="@{/css/color.css}"/>
<style type="text/css">
body {
background-color: #DADADA;
}
body > .grid {
height: 100%;
}
.image {
margin-top: -100px;
}
.column {
max-width: 450px;
}
</style>
<script>
$(document)
.ready(function() {
$('.ui.form')
.form({
fields: {
email: {
identifier : 'email',
rules: [
{
type : 'empty',
prompt : 'Please enter your e-mail'
},
{
type : 'email',
prompt : 'Please enter a valid e-mail'
}
]
},
password: {
identifier : 'password',
rules: [
{
type : 'empty',
prompt : 'Please enter your password'
},
{
type : 'length[6]',
prompt : 'Your password must be at least 6 characters'
}
]
}
}
})
;
})
;
</script>
</head>
<body>
<div class="ui middle aligned center aligned grid">
<div class="column">
<h2 class="ui teal header">
<div class="content">
Log-in to your account
</div>
</h2>
<form id="loginForm" class="ui large form" method="post"
th:action="@{/backstage/doLogin}"
action="/backstage/login">
<div class="ui stacked segment">
<div class="field">
<div class="ui left icon input">
<i class="user icon"></i>
<input type="text" name="username" placeholder="E-mail address">
</div>
</div>
<div class="field">
<div class="ui left icon input">
<i class="lock icon"></i>
<input type="password" name="password" placeholder="Password">
</div>
</div>
<div class="two fields">
<div class="field">
<div class="ui left icon input">
<i class="lock icon"></i>
<input type="text" name="captcha" placeholder="验证码">
</div>
</div>
<div class="ui field">
<img src="#" th:src="@{/captcha.jpg}"/>
</div>
</div>
<!-- <div class="ui fluid large teal submit button"-->
<!-- οnclick="function submitLoginForm() {-->
<!-- $('#loginForm').submit();-->
<!-- } submitLoginForm()">Login</div>-->
<input class="ui fluid large teal submit button" type="submit" value="Login"/>
</div>
<div class="ui error message"></div>
</form>
</div>
</div>
<script>
</script>
</body>
</html>