微服务迁移记(五):WEB层搭建(2)-SpringSecurity集成
一、redis搭建
二、WEB层主要依赖包
三、FeignClient通用接口
以上三项,参考《微服务迁移记(五):WEB层搭建(1)》
接下来,集成SpringSecruity,实现用户登录。
总体思路为:自定义UserDetails、UserDetailsService,重载WebSecurityConfigurerAdapter实现自定义表单登录,将菜单和按钮权限也扔到SpringSecruity的Session里。
四、SpringSecurity集成
1. 自定义MyUserDetails,实现UserDetails接口
1)我在里面多定义了一个UserEntity实体,通过get方法可以拿到这个实体,实现前台的一些业务逻辑。
RoleTreefuncEntity是功能权限树,也扔到session里。
2)isAccountNonExpired、isAccountNonLocked、isCredentialsNonExpired、isEnabled这几个方法,因为我直接从用户表取 del_flag=0的用户,不判断用户禁用或过期等状态,都直接返回true了。
package com.zyproject.web.secrity; import com.zyproject.entity.RoleTreefuncEntity;
import com.zyproject.entity.UserEntity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails; import java.util.Collection;
import java.util.List; /**
* @program: zyproject
* @description: 实现SpringSercrity UserDetails
* @author: zhouyu(zhouyu629 # qq.com)
* @create: 2020-02-12
**/
public class MyUserDetails implements UserDetails { private UserEntity userEntity; //用户实体
//将用户所有的角色菜单权限放到内存中,供校验使用
private List<RoleTreefuncEntity> roleTreefuncEntities; public MyUserDetails(UserEntity userEntity,List<RoleTreefuncEntity> roleTreefuncEntities){
this.userEntity = userEntity;
this.roleTreefuncEntities = roleTreefuncEntities;
} //获取用户真实姓名
public String getRealName(){
return userEntity.getUser_name();
} //获取用户实体
public UserEntity getUserEntity(){
return this.userEntity;
} //获取权限菜单
public List<RoleTreefuncEntity> getTreefuncEntities(){return this.roleTreefuncEntities;} @Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
} @Override
public String getPassword() {
return userEntity.getLogin_password();
} @Override
public String getUsername() {
return userEntity.getLogin_code();
} @Override
public boolean isAccountNonExpired() {
return true;
} @Override
public boolean isAccountNonLocked() {
return true;
} @Override
public boolean isCredentialsNonExpired() {
return true;
} @Override
public boolean isEnabled() {
return true;
}
}
2. 自定义MyUserDetailsService接口,实现UserDetailsService接口
package com.zyproject.web.secrity; import com.google.gson.Gson;
import com.zyproject.common.CodeEnum;
import com.zyproject.common.ResponseData;
import com.zyproject.entity.RoleTreefuncEntity;
import com.zyproject.entity.UserEntity;
import com.zyproject.web.service.TreeService;
import com.zyproject.web.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
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.Arrays;
import java.util.List; /**
* @program: zyproject
* @description: 实现SpringSecrity UserDetailService接口
* @author: zhouyu(zhouyu629 # qq.com)
* @create: 2020-02-12
**/
@Service
public class MyUserDetailService implements UserDetailsService {
@Autowired
private UserService userService;
@Autowired
private TreeService treeService; @Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
ResponseData<UserEntity> userResult = userService.findByLoginname(s);
UserEntity user = new UserEntity();
if(userResult.getCode() == CodeEnum.SUCCESS.getCode()){
user = userResult.getData(UserEntity.class);
ResponseData rightResult = treeService.getRoleTreefuncByUserid(user.getUser_id());
Gson gson = new Gson();
List<RoleTreefuncEntity> roleTreefuncEntities = Arrays.asList(gson.fromJson(gson.toJson(rightResult.getData()),RoleTreefuncEntity[].class));
return new MyUserDetails(user,roleTreefuncEntities);
}else{
throw new UsernameNotFoundException(s);
}
}
}
3. SecurityConfiguration配置
1) 覆写protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder),实现MD5密码校验
2) protected void configure(HttpSecurity httpSecurity),实现自定义表单登录
package com.zyproject.web.secrity; import org.springframework.beans.factory.annotation.Autowired;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder; /**
* @program: zyproject
* @description: SpringSercrity配置
* @author: zhouyu(zhouyu629 # qq.com)
* @create: 2020-02-12
**/
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired
private MyUserDetailService myUserDetailService; @Autowired
private MyAuthenctiationFailureHandler myAuthenctiationFailureHandler; @Autowired
private MyAuthenctiationSucessHandler myAuthenctiationSucessHandler; @Override
protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception{
authenticationManagerBuilder.userDetailsService(myUserDetailService).passwordEncoder(new PasswordEncoder() {
@Override
public String encode(CharSequence charSequence) {
return MD5Util.encode((String)charSequence);
} @Override
public boolean matches(CharSequence charSequence, String s) {
return s.equals(MD5Util.encode((String)charSequence));
}
});
} @Override
protected void configure(HttpSecurity httpSecurity) throws Exception{
httpSecurity.headers().frameOptions().disable();
httpSecurity
.authorizeRequests()
.antMatchers("/manage/error","/manage/login/**","/manage/login-submit","/manage/images/**","/manage/js/**","/manage/css/**","/manage/fonts/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
//指定登录路径
.loginPage("/manage/login")
.loginProcessingUrl("/manage/login-submit") //表单请求的路径,貌似无用,已经在config里做密码校验了
.failureHandler(myAuthenctiationFailureHandler)
.successHandler(myAuthenctiationSucessHandler)
.failureUrl("/manage/error?key=1002")
.defaultSuccessUrl("/manage/index")
.usernameParameter("username")
.passwordParameter("password")
//必须允许所有用户访问我们的登录页(例如未验证的用户,否则验证流程就会进入死循环)
.permitAll()
.and()
.sessionManagement()
.invalidSessionUrl("/manage/error?key=timeout");
//默认都会产生一个hiden标签 里面有安全相关的验证 防止请求伪造 这边我们暂时不需要 可禁用掉
httpSecurity.csrf().disable();
} @Override
public void configure(WebSecurity webSecurity) throws Exception{
super.configure(webSecurity);
}
}
五、FreeMarker集成
待续
六、权限管理
待续
微服务迁移记(五):WEB层搭建(2)-SpringSecurity集成的更多相关文章
- 微服务迁移记(五):WEB层搭建(5)-集成ueditor编辑器,伪分布式图片上传
一.redis搭建 二.WEB层主要依赖包 三.FeignClient通用接口 以上三项,参考<微服务迁移记(五):WEB层搭建(1)> 四.SpringSecurity集成 参考:< ...
- 微服务迁移记(五):WEB层搭建(3)-FreeMarker集成
一.redis搭建 二.WEB层主要依赖包 三.FeignClient通用接口 以上三项,参考<微服务迁移记(五):WEB层搭建(1)> 四.SpringSecurity集成 参考:< ...
- 微服务迁移记(五):WEB层搭建(4)-简单的权限管理
一.redis搭建 二.WEB层主要依赖包 三.FeignClient通用接口 以上三项,参考<微服务迁移记(五):WEB层搭建(1)> 四.SpringSecurity集成 参考:< ...
- 微服务迁移记(五):WEB层搭建(1)
WEB层是最终表现层,注册至注册中心,引用接口层(不需要引用实现层).公共服务层.用户登录使用SpringSecurity,Session保存在redis中,权限管理没有用SpringSecurity ...
- docker微服务部署之:二、搭建文章微服务项目
docker微服务部署之:一,搭建Eureka微服务项目 一.新增demo_article模块,并编写代码 右键demo_parent->new->Module->Maven,选择M ...
- docker微服务部署之:三,搭建Zuul微服务项目
docker微服务部署之:二.搭建文章微服务项目 一.新增demo_eureka模块,并编写代码 右键demo_parent->new->Module->Maven,选择Module ...
- docker微服务部署之:一,搭建Eureka微服务项目
先说明一下docker需要搭建的微服务的基本情况: 项目情况:一个demo_parent项目,下面三个子模块:demo_eureka(eureka服务).demo_article(文章服务).demo ...
- 微服务实践(五):微服务的事件驱动数据管理 - DockOne.io
原文:微服务实践(五):微服务的事件驱动数据管理 - DockOne.io [编者的话]本文是使用微服务创建应用系列的第五篇文章.第一篇文章介绍了微服务架构模式,并且讨论了使用微服务的优缺点:第二和第 ...
- .Net微服务实践(五)[服务发现]:Consul介绍和环境搭建
目录 介绍 服务发现 健康检查.键值存储和数据中心 架构 Consul模式 环境安装 HTTP API 和Command CLI 示例API介绍 最后 在上篇.Net微服务实践(四)[网关]:Ocel ...
随机推荐
- 新建maven项目总是需要重新选择maven的配置文件
解决办法: other settings->settings for new projects... 找到maven设置自己的目录和配置
- Python线程池与进程池
Python线程池与进程池 前言 前面我们已经将线程并发编程与进程并行编程全部摸了个透,其实我第一次学习他们的时候感觉非常困难甚至是吃力.因为概念实在是太多了,各种锁,数据共享同步,各种方法等等让人十 ...
- 别逃避,是时候来给JVM一记重锤了
今天是猿灯塔“365天原创计划”第2天. 今天讲: 为什么写这个主题呢? 之前看到不少同学在讨论, 今天呢火星哥抽出点时间来帮大家整理一下关于JVM的一些知识点 一.JVM是什 ...
- innobackupex 数据库备份
一,安装innobackupex CentOS: yum install percona-xtrabackup 二,备份数据 备份: innobackupex --user=user --passwo ...
- 「疫期集训day0」启程
看了看几乎所有学长都是写的博客,所以写的博客 由于是第一回集训,考得都是老题(虽然有些还不会) 感受1:我调试好蒻呃,调试巨蒻,T1lis模板5分切,结果T2T3T4调了将近了两个小时,先是T2路径输 ...
- python提取json字符串的值
json_str={ "actor":"邓超", "age":35, "book":[ "英语", ...
- Freemarker 使用记录
1.数字超过1000时会有逗号 ,设置数据格式 <#setting number_format="#"> 2.数据叠加 求总计: 1)定义变量:<#assign ...
- .NET程序运行原理及基本概念详解
一.引言 我们知道在Java中有虚拟机,代码运行时虚拟机把Java语言编译成与机器无关的字节码,然后再把字节码编译成机器指令执行,那么在.NET中程序是如何运行的呢?其实运行原理是一样的,.NET中的 ...
- Python-break/continue
break:用于终止整个循环 continue:用于终止本次循环,而不终止整个循环的执行
- 最佳开发工具大全,GitHub Star 6.2k+
一位曾经的谷歌工程师,花费两年时间,辛苦整理了一份清单.本文转自量子位,作者晓查.栗子.方驭洋,如有侵,可删! 这个名为 "xg2xg" 的清单,原本是这位前谷歌工程师(ex-Go ...