Security的基本介绍搜搜别的博客看吧,我是来贴代码的(如果是新手,一定要多看看基本介绍,搭建,配置等)
最重要的Security配置代码
package com.**.config;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import com.**.core.service.CustomerUserService;
@Configuration
@EnableWebSecurity //打开SpringSecurity的web支持
class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
UserDetailsService customerUserService(){
return new CustomerUserService();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//在内存中创建一个ADMIN角色的用户
// auth.inMemoryAuthentication().passwordEncoder(new MyPasswordEncoder()) //5.0以上的security版本需要一个密码编码器 需要自定义
// .withUser("testoc").password("0bf1e4984cd85c0eb227856324b72901").roles("supperManager");
//此处可以创建多个用户
// auth.inMemoryAuthentication().passwordEncoder(new MyPasswordEncoder())
// .withUser("demo").password("demo").roles("USER");
//使用数据库管理用户
//customerUserService()是获取数据库动态用户和角色数据 new MyPasswordEncoder()提供密码的MD5加密对比
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/assets/**","/login").permitAll() //对项目主路径和css,js静态资源放行
.anyRequest().authenticated() //其他路径进行权限验证
.and()
.logout().logoutSuccessUrl("/login?logout")
.deleteCookies("remember-me").permitAll()
.logoutSuccessUrl("/login").permitAll() //对注销放行
.and().rememberMe().rememberMeParameter("remember-me").tokenValiditySeconds(1209600)//记住密码时效
.and()
.formLogin().loginPage("/login").successHandler(new AuthenticationSuccessHandler() {//登陆成功后操作
@Override
public void onAuthenticationSuccess(HttpServletRequest arg0, HttpServletResponse arg1, Authentication arg2)
throws IOException, ServletException {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal != null && principal instanceof UserDetails) {
UserDetails user = (UserDetails) principal;
System.out.println("loginUser:"+user.getUsername());
//维护在session中
arg0.getSession().setAttribute("userDetail", user);
arg1.sendRedirect("/index.do");
}
}
}).permitAll();//.loginPage("/login")
}
@Override
public void configure(WebSecurity web) throws Exception{
// super.configure(web);
//忽略静态资源的权限拦截
web.ignoring().antMatchers("/assets/**","**/jsp/**");
}
}
package com.**.config;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import com.**.RunMain;
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(RunMain.class);
}
}
提供密码对比的代码
package com.**.config;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.**.core.service.CustomerUserService;
import com.**.core.util.MD5Util;
public class MyPasswordEncoder implements PasswordEncoder {
public String encode(CharSequence rawPassword) {
//加密方法
return rawPassword.toString();
}
public boolean matches(CharSequence rawPassword, String encodedPassword) {
try {//个人方法将密码和用户id加密 大家可以自定义
Integer id = CustomerUserService.getUser().getId();
if(MD5Util.checkPasswordWithSalt(rawPassword.toString(),encodedPassword, id)) {//参数(页面明文密码,数据库加密密码,用户id)
return true;
}
return false;
}catch(Exception e){
return false;
}
}
public static void main(String[] args) {
System.out.println(MD5Util.getMD5EncodedPasswordWithSalt("0bf1e4984cd85c0eb227856324b72901",33));
}
}
动态获取用户数据代码
package com.**.core.service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import com.**.core.entity.Role;
import com.**.core.entity.User;
import com.**.core.mapper.RoleMapper;
import com.**.core.mapper.UserMapper;
//继承UserDetailsService 会自动找到loadUserByUsername方法获取动态数据
public class CustomerUserService implements UserDetailsService {
@Autowired
private UserMapper userMapper;
@Autowired
private RoleMapper roleMapper;
static User user;
public static User getUser() {
return user;
}
public static void setUser(User user) {
CustomerUserService.user = user;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User sysUser = userMapper.loadUserByUsername(username);
if(sysUser == null){
throw new UsernameNotFoundException("用户名不存在");
}
user = sysUser;
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
Role role = roleMapper.selectByPrimaryKey(new BigDecimal(sysUser.getRoleid()));
sysUser.setRole(role);//重点"ROLE_"+role.getCode() ROLE_必须加 判断权限会以ROLE_开头判断 看看源码就可以理解
authorities.add(new SimpleGrantedAuthority("ROLE_"+role.getCode()));
return new org.springframework.security.core.userdetails.User(sysUser.getLoginName(),sysUser.getPassword(),authorities);
}
}
接下来贴前端页面代码
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ page isELIgnored ="false" %>
<%@ include file="/page/common/pub.jsp" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Login page</title>
<link href="<c:url value='${basePath}assets/pages/css/bootstrap.css' />" rel="stylesheet"></link>
<%-- <link href="<c:url value='${basePath}assets/pages/css/app.css' />" rel="stylesheet"></link> --%>
<link href="${basePath}assets/pages/css/ynz/common/static.css?version=20170817024514" rel='stylesheet' type='text/css' />
<link href="${basePath}assets/pages/css/ynz/login/login.css?version=20170817024514" rel='stylesheet' type='text/css' />
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.css" />
<style>
.input-group{
line-height: 60px;
width: 300px;
}
</style>
</head>
<body>
<div id="mainWrapper">
<div class="login-container">
<div class="login-card">
<div class="login-form" style="position: absolute;left: 45%;top: 35%;">
<form action="/login" method="POST" class="form-horizontal" id="loginForm">
<c:if test="${param.error != null}">
<div class="alert alert-danger">
<p>Invalid username and password.</p>
</div>
</c:if>
<c:if test="${param.logout != null}">
<div class="alert alert-success">
<p>You have been logged out successfully.</p>
</div>
</c:if>
<div class="input-group input-sm">
<label class="input-group-addon" for="username"><i class="fa fa-user"></i></label>
<input type="text" class="form-control" id="username" name="username" placeholder="Enter Username" required>
</div>
<div class="input-group input-sm">
<label class="input-group-addon" for="password"><i class="fa fa-lock"></i></label>
<input type="password" class="form-control" id="password" name="password" placeholder="Enter Password" required>
</div>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
<div id="" class="choice">
<input type="checkbox" name="remember-me">记住密码
<!-- <i class="remberPass" id="remberPass"></i><span>记住密码</span> -->
</div>
<div class="form-actions" style="margin-left: 20px;width: 250px">
<input type="submit" id="loginSys" class="btn btn-block btn-primary btn-default" value="登录">
</div>
</form>
</div>
</div>
</div>
</div>
</body>
</html>
退出登录
<form action="/logout" method="POST">
<input type="submit" value="退出登录">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
登录是自定义页面,所以转页面是用的get方法
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String loginPage() {
return "login/login";
}
提交登录是post
退出登录是security的方法,用form表单post提交