SpringBoot 集成Spring security
Spring security作为一种安全框架,使用简单,能够很轻松的集成到springboot项目中,下面讲一下如何在SpringBoot中集成Spring Security.使用gradle项目管理工具。
准备数据,
CREATE TABLE `user` (
`uid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`roles` varchar(200) DEFAULT 'USER',
PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; insert into `user` values(0,'admin','admin','SUPER,role'); //给不同个用户配置不同的权限
insert into `user` values(1,'role','role','role');
1:配置buildgradle,添加spring boot插件和spring security
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath('org.springframework.boot:spring-boot-gradle-plugin:1.5.9.RELEASE')
}
}
group "com.li"
version "1.0-SNAPSHOT"
apply plugin: "java" //java 插件
apply plugin: "org.springframework.boot" //spring boot 插件
apply plugin: "io.spring.dependency-management" apply plugin: "application" //应用
mainClassName = "com.li.SpringBootShrioApplication"
sourceCompatibility = 1.8 repositories {
mavenCentral()
} dependencies {
compile("org.springframework.boot:spring-boot-starter-web",
"org.springframework.boot:spring-boot-starter-activemq",
"org.springframework.boot:spring-boot-starter-test",
"org.springframework.boot:spring-boot-starter-cache",
"org.springframework.boot:spring-boot-devtools",
"mysql:mysql-connector-java:5.1.35",
'org.apache.commons:commons-lang3:3.4',
'org.apache.commons:commons-pool2',
"org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.0",
'org.apache.logging.log4j:log4j-core:2.7',
'org.springframework.boot:spring-boot-starter-security',
'org.springframework.boot:spring-boot-starter-thymeleaf',
'org.thymeleaf.extras:thymeleaf-extras-springsecurity4', //thymeleaf模板,集成 springsecurity4
'net.sourceforge.nekohtml:nekohtml' ) testCompile group: 'junit', name: 'junit', version: '4.12' }
2:配置spring boot, application.yml
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/springsecurity
username: root
password: 1367356
thymeleaf:
mode: LEGACYHTML5
cache: false devtools:
restart:
enabled: true
server:
port: 8081
mybatis:
mapper-locations: classpath:mybatis/mapper/*.xml #Mapper所在的配置文件路径,进行扫描
config-location: classpath:mybatis/mybatis-config.xml # mybaits-config文件
3:配置Spring Security
WebSecurityConfig.java 继承 WebSecurityConfigurerAdapter.
当访问项目时,安全管理器按照配置进行拦截,验证通过才能访问Controller相应的路径。
package com.li.security; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
} @Autowired
MyUserDetailsService myUserDetailsService; @Bean
public AuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(myUserDetailsService);
authenticationProvider.setPasswordEncoder(this.bCryptPasswordEncoder());
return authenticationProvider;
} @Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailsService).passwordEncoder(this.bCryptPasswordEncoder());
} @Override
protected void configure(HttpSecurity http) throws Exception {
// String[] s=null;
http.csrf().disable()
.authorizeRequests()
.antMatchers("/user/settings").authenticated() // order matters
.antMatchers("/", "/js/**", "/css/**","/avatar/**", "/images/**", "/fonts/**", "/bootstrap-select/**", "/bootstrap-datetimepicker/**", "/custom/**", "/daterangepicker/**", "/chartjs/**").permitAll() // these paths are configure not to require any authentication
.antMatchers("/post/**").permitAll() // all posts are allowed to be viewed without authentication
// .antMatchers("/user/**").permitAll() // all user profiles are allowed to be viewed without authentication
.antMatchers("/category/**").permitAll() // all categories are allowed to be viewed without authentication
.antMatchers("/user/registration").permitAll()
.antMatchers("/avatar/**").permitAll() // temp
.antMatchers("/visitor/**").permitAll() // temp
// .antMatchers("/admin/**").hasAnyRole("SUPER","USER")
// .antMatchers("/admin/**").
// .antMatchers("/admin/**").hasAnyRole(s)
.anyRequest().authenticated() // every request requires the user to be authenticated
.and()
.formLogin()
.loginPage("/user/login")
.permitAll() // login URL can be accessed by anyone
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutSuccessUrl("/?logout")
.permitAll();
}
}
验证:对访问用户进行验证
package com.li.security; import com.li.dao.User;
import com.li.service.UserService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
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 org.springframework.stereotype.Service; import java.util.ArrayList;
import java.util.List; @Service
public class MyUserDetailsService implements UserDetailsService{ Logger logger = LogManager.getLogger(MyUserDetailsService.class);
@Autowired
private UserService userService; @Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = this.userService.findUserByUserName(username);
logger.debug(user.getUserName()+"密码"+user.getPassword());
if(null == user) {
throw new UsernameNotFoundException("Can't find user by username: " + username);
} List<SimpleGrantedAuthority> grantedAuthorities = new ArrayList<>();
// grant roles to user
for (String role : user.getRolesSet()) {
logger.debug(role);
grantedAuthorities.add(new SimpleGrantedAuthority(role)); //认证
}
// user.setGrantedAuthorities(authorities); //用于登录时 @AuthenticationPrincipal 标签取值
return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassword(), grantedAuthorities); //角色认证
}
}
4: Controller ,Service,Dao层编写
验证通过,Controller对相应的http处理。可以在每个http上面指定相应的访问权限
package com.li.controller; import com.li.dao.User;
import com.li.service.UserService;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.config.ResourceNotFoundException;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import javax.validation.Valid;
import java.util.Map; @Controller
public class UserController { @Autowired
UserService userService; @RequestMapping(value = "/", method = RequestMethod.GET)
public String login() {
System.out.println("home");
return "forum/home";
} @RequestMapping(value = "/user/login", method = RequestMethod.GET)
public String displayLoginPage(Model model) {
System.out.println("进入");
model.addAttribute("title", "用户登陆");
return "forum/user-login"; //登录界面,验证没通过。
} /**
* 用户注册
* @param model
* @return
*/
@RequestMapping(value = "/user/registration", method = RequestMethod.GET)
public String showRegistrationPage(Model model) {
System.out.println("registrationGet");
model.addAttribute("userDto", new User());
return "forum/user-registration"; //注册页面
} @RequestMapping(value = "/user/registration", method = RequestMethod.POST) //提交注册
public String registerNewUser(@ModelAttribute("userDto") User user,BindingResult bindingResult,
Model model, HttpServletRequest request) {
System.out.println("registrationPost");
Map<String, Object> attributes = this.userService.registerUserAccount(user);
model.addAllAttributes(attributes);
return "forum/user-registration-result";
} @PreAuthorize("hasAuthority('SUPER')") //需要SUPER用户才能通过该路径,第一步通过配置验证,没有用户登录,将会拦截,让用户登录,登录成功,访问该路径时进行角色验证。
@RequestMapping(value = "/admin/admin", method = RequestMethod.GET)
public String deletePost() {
return "admin/admin";
} }
Service
package com.li.service; import com.li.dao.User; import javax.servlet.http.HttpServletRequest;
import java.util.Map; public interface UserService {
public User findUserByUserName(String userName);
public Map<String, Object> registerUserAccount(User user);
}
SeriviceImpl,对用户密码加密存储,
package com.li.service.impl; import com.li.dao.User;
import com.li.dao.mapper.UserMapper;
import com.li.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.UUID; @Service
public class UserServiceImpl implements UserService{ @Autowired
BCryptPasswordEncoder bCryptPasswordEncoder; @Autowired
UserMapper userMapper; @Override
public User findUserByUserName(String userName) {
return userMapper.findByUserName(userName);
} @Override
public Map<String, Object> registerUserAccount(User userDto) {
Map<String, Object> attributes = new HashMap<>(); // save newly registered user
User user = new User(); user.setPassword(bCryptPasswordEncoder.encode(userDto.getPassword())); //保存时应该将密码编码
user.setUserName(userDto.getUserName());
// user.activated(true);
user.setRoles("USER");
// user.setConfirmationToken(UUID.randomUUID().toString()); // save new user and get number of affected row
// logger.debug("用户注册");
int affectedRow = userMapper.save(user);// populate attributes
String registrationResult = affectedRow == 1 ? "success" : "failure";
attributes.put("userRegistrationResult", registrationResult);
return attributes;
}
}
DaoMapper
package com.li.dao.mapper; import com.li.dao.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; @Mapper
public interface UserMapper {
public User findByUserName(String username); public int save(@Param("user") User user);
}
普通User类
package com.li.dao; import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set; /**
* 实验室网站用户
*/
public class User {
public int id;
public String userName;
public String password;
public String roles; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public String getRoles() {
return roles;
} public void setRoles(String roles) {
this.roles = roles;
} public Set<String> getRolesSet() { //获取用户权限
if (null == roles) {
return null;
}
return Collections.unmodifiableSet(
new HashSet<String>(Arrays.asList(getRoles().split(","))));
} public void addRole(String role) {
String currRoles = this.getRoles();
if (null == currRoles || this.getRoles().contains(role)) {
return;
}
this.setRoles(currRoles + "," + role);
} @Override
public String toString() {
return "User{" +
"id=" + id +
", userName='" + userName + '\'' +
", password='" + password + '\'' +
", roles='" + roles + '\'' +
'}';
}
}
5:编写项目的前台页面,static文件夹下面,不同权限的页面放到不同种类下面
SpringBoot 集成Spring security的更多相关文章
- SpringBoot集成Spring Security入门体验
一.前言 Spring Security 和 Apache Shiro 都是安全框架,为Java应用程序提供身份认证和授权. 二者区别 Spring Security:重量级安全框架 Apache S ...
- SpringBoot集成Spring Security(7)——认证流程
文章目录 一.认证流程 二.多个请求共享认证信息 三.获取用户认证信息 在前面的六章中,介绍了 Spring Security 的基础使用,在继续深入向下的学习前,有必要理解清楚 Spring Sec ...
- SpringBoot集成Spring Security(6)——登录管理
文章目录 一.自定义认证成功.失败处理 1.1 CustomAuthenticationSuccessHandler 1.2 CustomAuthenticationFailureHandler 1. ...
- SpringBoot集成Spring Security(5)——权限控制
在第一篇中,我们说过,用户<–>角色<–>权限三层中,暂时不考虑权限,在这一篇,是时候把它完成了. 为了方便演示,这里的权限只是对角色赋予权限,也就是说同一个角色的用户,权限是 ...
- SpringBoot集成Spring Security(4)——自定义表单登录
通过前面三篇文章,你应该大致了解了 Spring Security 的流程.你应该发现了,真正的 login 请求是由 Spring Security 帮我们处理的,那么我们如何实现自定义表单登录呢, ...
- SpringBoot集成Spring Security(2)——自动登录
在上一章:SpringBoot集成Spring Security(1)——入门程序中,我们实现了入门程序,本篇为该程序加上自动登录的功能. 文章目录 一.修改login.html二.两种实现方式 2. ...
- SpringBoot集成Spring Security
1.Spring Security介绍 Spring security,是一个强大的和高度可定制的身份验证和访问控制框架.它是确保基于Spring的应用程序的标准 --来自官方参考手册 Spring ...
- SpringBoot集成Spring Security(1)——入门程序
因为项目需要,第一次接触 Spring Security,早就听闻 Spring Security 功能强大但上手困难,学习了几天出入门道,特整理这篇文章希望能让后来者少踩一点坑(本文附带实例程序,请 ...
- SpringBoot集成Spring Security(授权与认证)
⒈添加starter依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifact ...
随机推荐
- Unity战斗系统之AI自主决策
http://www.taikr.com/course/448/tasks http://www.xuanyusong.com/archives/1840 http://www.cnblogs.com ...
- VC++ : VS2008 使用ATL开发COM组件
新建ATL Project,工程名命名为MyAtlCom: 出现工程 向导,一路“Next”: Add class,点击添加 ATL Simple Object , 类名CStatistic, 接口I ...
- day01<计算机基础知识&Java语言基础>
计算机基础知识(计算机概述) 计算机基础知识(软件开发和计算机语言概述) 计算机基础知识(人机交互) 计算机基础知识(键盘功能键和快捷键) 计算机基础知识(如何打开DOS控制台) 计算机基础知识(常见 ...
- com.thoughtworks.xstream.converters.ConversionException
使用webService调用接口,返回的是xml格式,运用xstream解析的时候,出现了如下的错误: Exception in thread "Timer-1" com.thou ...
- Qt监控Access数据库
配置文件setup.ini内容 [General] DBFilePath=C:/Users/WangGang/Desktop/Database1.accdb DBUserName= DBPasswor ...
- 使用fetch-jsonp进行跨域以及参数的传递
其实fetch-jsonp的官方文档里面已经写得很详细了,连接如下:https://github.com/camsong/fetch-jsonp:但是由于它本身没有多少demo,所以自己在上手的时候遇 ...
- php学习十一:组合
我们在类当中我往往会用到一些对象,此时的继承就无法满足我们的需求,这个时候我们需要用到组合.继承如果是is..a的关系,那么组合就是has...a的关系,直接在本类里面声明即可,不过声明的是一个对象 ...
- Axis2开发实例
1.下载①axis2-1.7.4-bin.zip.②axis2-1.7.4-war.zip.③axis2-eclipse-service-plugin-1.7.4.zip.④axis2-eclipse ...
- poj_3662 最小化第k大的值
题目大意 有N个节点以及连接的P个无向边,现在要通过这P条边从1号节点连接到N号节点.若无法连接成功,则返回-1:若能够连接成功,那么其中用到了L条边,这L条边中有K条边可以免费,L-K条边不能免费, ...
- 【WebService】使用jaxb完成对象和xml的转换
package com.slp.jxmarshaller; /** * Created by sanglp on 2017/2/26. */ public class ClassName { priv ...