增加博客权限认证授权整体流程

This commit is contained in:
zxm 2018-08-19 22:38:23 +08:00 committed by meng
parent 006149e5f3
commit ee49087067
21 changed files with 685 additions and 492 deletions

View File

@ -28,33 +28,4 @@
<version>4.12</version>
</dependency>
</dependencies>
<!-- <build>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.5</version>
<configuration>
<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
<executions>
<execution>
<id>Generate MyBatis Artifacts</id>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>-->
</project>

View File

@ -6,6 +6,8 @@ import com.alibaba.fastjson.JSONObject;
import com.len.base.BaseController;
import com.len.entity.BlogLabel;
import com.len.service.BlogLabelService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@ -35,6 +37,7 @@ public class LabelController extends BaseController {
* @return
*/
@GetMapping("/getLabel")
@RequiresRoles("admin")
public JSONArray label() {
List<BlogLabel> blogLabels = blogLabelService.selectAll();
JSONArray array = JSONArray.parseArray(JSON.toJSONString(blogLabels));

View File

@ -1,15 +1,24 @@
package com.len.controller;
import com.len.entity.SysRole;
import com.len.entity.SysRoleUser;
import com.len.entity.SysUser;
import com.len.service.RoleService;
import com.len.service.RoleUserService;
import com.len.service.SysUserService;
import com.len.util.JWTUtil;
import com.len.util.JsonUtil;
import com.len.util.Md5Util;
import org.apache.shiro.authz.UnauthorizedException;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authc.UnknownAccountException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import tk.mybatis.mapper.entity.Condition;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author zhuxiaomeng
@ -17,23 +26,48 @@ import org.springframework.web.bind.annotation.RestController;
* @email 154040976@qq.com
*/
@RestController
@RequestMapping("/blog")
@RequestMapping("/")
public class SignController {
@Autowired
private SysUserService sysUserService;
@PostMapping("/login")
public String login(@RequestParam("username") String username,
@RequestParam("password") String password) {
SysUser user=new SysUser();
user.setUsername(username);
SysUser sysUser=sysUserService.selectOne(user);
String pass = Md5Util.getMD5(password, username);
if (sysUser.getPassword().equals(pass)) {
return JWTUtil.sign(username, password);
} else {
throw new UnauthorizedException();
@Autowired
private RoleService roleService;
@Autowired
private RoleUserService roleUserService;
@ApiOperation(value = "/blogLogin", httpMethod = "POST", notes = "登录method")
@PostMapping(value = "/blogLogin")
public JsonUtil blogLogin(SysUser user) {
String pass = user.getPassword();
user.setPassword(null);
SysUser sysUser = sysUserService.selectOne(user);
if (sysUser == null) {
throw new UnknownAccountException("用户名或密码错误");
}
String md5 = Md5Util.getMD5(pass, sysUser.getUsername());
if (!md5.equals(sysUser.getPassword())) {
throw new UnknownAccountException("用户名或密码错误");
}
Condition condition = new Condition(SysRoleUser.class);
condition.createCriteria().andEqualTo("userId", user.getId());
List<SysRoleUser> sysRoleUsers = roleUserService.selectByExample(condition);
List<String> roleList = sysRoleUsers
.stream()
.map(SysRoleUser::getRoleId)
.collect(Collectors.toList());
condition = new Condition(SysRole.class);
condition.createCriteria().andIn("id", roleList);
List<SysRole> sysRoles = roleService.selectByExample(condition);
List<String> roleNames = sysRoles
.stream()
.map(SysRole::getRoleName)
.collect(Collectors.toList());
return new JsonUtil(true, JWTUtil.sign(sysUser.getUsername(), roleNames, sysUser.getPassword()), 200);
}
}

View File

@ -0,0 +1,98 @@
package com.len.core;
import com.len.base.CurrentMenu;
import com.len.base.CurrentRole;
import com.len.base.CurrentUser;
import com.len.core.shiro.ShiroUtil;
import com.len.entity.SysUser;
import com.len.service.MenuService;
import com.len.service.RoleMenuService;
import com.len.service.RoleUserService;
import com.len.service.SysUserService;
import com.len.util.JWTUtil;
import com.len.util.JwtToken;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author zhuxiaomeng
* @date 2017/12/4.
* @email 154040976@qq.com
*/
@Service
public class BlogRealm extends AuthorizingRealm {
@Autowired
private SysUserService userService;
@Autowired
private MenuService menuService;
@Autowired
private RoleUserService roleUserService;
@Autowired
private RoleMenuService roleMenuService;
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof JwtToken;
}
/**
* 获取认证
*
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
String name = (String) principalCollection.getPrimaryPrincipal();
JWTUtil.getUsername(name);
//根据用户获取角色 根据角色获取所有按钮权限
CurrentUser cUser = (CurrentUser) ShiroUtil.getSession().getAttribute("curentUser");
for (CurrentRole cRole : cUser.getCurrentRoleList()) {
info.addRole(cRole.getId());
}
for (CurrentMenu cMenu : cUser.getCurrentMenuList()) {
if (!StringUtils.isEmpty(cMenu.getPermission())) {
info.addStringPermission(cMenu.getPermission());
}
}
return info;
}
/**
* 获取授权
*
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
throws AuthenticationException {
JwtToken token = (JwtToken) authenticationToken;
String username = JWTUtil.getUsername(token.getToken());
if (StringUtils.isEmpty(username)) {
throw new UnknownAccountException("令牌无效");
}
SysUser s = userService.login(username);
if (s == null) {
throw new UnknownAccountException("用户名或密码错误");
}
if (!JWTUtil.verify(token.getToken(), username, s.getPassword())) {
throw new UnknownAccountException("用户名或密码错误");
}
return new SimpleAuthenticationInfo(token.getToken(), token.getToken(), getName());
}
}

View File

@ -0,0 +1,72 @@
package com.len.core;
import cn.hutool.core.util.StrUtil;
import com.len.util.CustomUsernamePasswordToken;
import com.len.util.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 验证器增加了登录次数校验功能
* 限制尝试登陆次数,防止暴力破解
*/
@Slf4j
public class BlogRetryLimitCredentialsMatcher extends HashedCredentialsMatcher {
/* private Cache<String, AtomicInteger> loginRetryCache;
private int maxRetryCount = 5;
*//*public void setMaxRetryCount(int maxRetryCount) {
this.maxRetryCount = maxRetryCount;
}
public BlogRetryLimitCredentialsMatcher(){
}*//*
*//**
* @param cacheManager
* @param maxRetryCount 最大尝试次数
*//*
public BlogRetryLimitCredentialsMatcher(CacheManager cacheManager, int maxRetryCount) {
this.maxRetryCount = maxRetryCount;
this.loginRetryCache = cacheManager.getCache("loginRetryCache");
}
public BlogRetryLimitCredentialsMatcher(CacheManager cacheManager) {
this(cacheManager, 5);
}
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
CustomUsernamePasswordToken token1 = (CustomUsernamePasswordToken) token;
String username = token1.getUsername();
if (StringUtils.isEmpty(username) && !StringUtils.isEmpty(token1.getToken())) {
username = JWTUtil.getUsername(token1.getToken());
}
//retry count + 1
AtomicInteger retryCount = loginRetryCache.get(username) == null
? new AtomicInteger(0) : loginRetryCache.get(username);
log.info("retryCount:{}, username:{}", retryCount, username);
if (retryCount.incrementAndGet() > this.maxRetryCount) {
log.warn("username: {} tried to login more than {} times in perid", username, this.maxRetryCount);
throw new ExcessiveAttemptsException(StrUtil.format("username: {} tried to login more than {} times in perid", username, this.maxRetryCount));
}
boolean matches = super.doCredentialsMatch(token1, info);
if (matches) {
loginRetryCache.remove(username);
} else {
loginRetryCache.put(username, retryCount);
log.info(String.valueOf(retryCount.get()));
}
return matches;
}*/
}

View File

@ -0,0 +1,47 @@
package com.len.core;
import com.len.core.exception.UnauthorizedException;
import com.len.util.JwtToken;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
/**
* @author zhuxiaomeng
* @date 2018/8/19.
* @email 154040976@qq.com
*/
public class MyBasicHttpAuthenticationFilter extends BasicHttpAuthenticationFilter {
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
if (isLoginAttempt(request, response)) {
try {
executeLogin(request, response);
return true;
} catch (Exception e) {
throw new UnauthorizedException(e.getMessage());
}
} else {
throw new UnauthorizedException("禁止访问");
}
}
@Override
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String token = httpServletRequest.getHeader("Authorization");
JwtToken jwtToken = new JwtToken(token, "BlogLogin");
getSubject(request, response).login(jwtToken);
return true;
}
@Override
protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) {
HttpServletRequest req = (HttpServletRequest) request;
String authorization = req.getHeader("Authorization");
return authorization != null;
}
}

View File

@ -0,0 +1,13 @@
package com.len.core.exception;
/**
* @author zhuxiaomeng
* @date 2018/8/19.
* @email 154040976@qq.com
* 未授权异常
*/
public class UnauthorizedException extends RuntimeException {
public UnauthorizedException(String msg) {
super(msg);
}
}

View File

@ -12,7 +12,7 @@ import java.util.List;
* @email 154040976@qq.com
* mapper封装 crud
*/
public interface BaseMapper<T, E extends Serializable> extends tk.mybatis.mapper.common.BaseMapper<T>, MySqlMapper<T>, IdsMapper<T> {
public interface BaseMapper<T, E extends Serializable> extends tk.mybatis.mapper.common.Mapper<T>, MySqlMapper<T>, IdsMapper<T> {
/*
*//**
* 根据id删除

View File

@ -1,8 +1,10 @@
package com.len.base;
import com.len.util.ReType;
import org.apache.ibatis.session.RowBounds;
import java.io.Serializable;
import java.util.List;
/**
* @author zhuxiaomeng
@ -10,54 +12,60 @@ import java.io.Serializable;
* @email 154040976@qq.com
* 通用service层
*/
public interface BaseService<T, E extends Serializable> extends BaseMapper<T, E> {
/**
* 根据id删除
* @param id
* @return
*//*
int deleteByPrimaryKey(E id);
public interface BaseService<T, E extends Serializable> {
*//**
* 插入
* @param record
* @return
*//*
int insert(T record);
public List<T> select(T t);
*//**
*插入非空字段
* @param record
* @return
*//*
int insertSelective(T record);
public List<T> selectAll();
*//**
* 根据id查询
* @param id
* @return
*//*
T selectByPrimaryKey(E id);
public List<T> selectByIds(String ids);
*//**
* 更新非空数据
* @param record
* @return
*//*
int updateByPrimaryKeySelective(T record);
public int selectCount(T t);
*/
public int deleteByPrimaryKey(E id);
/**
* 更新
*
* @param record
* @return
*//*
int updateByPrimaryKey(T record);
public int insert(T record);
public int insertSelective(T record);
public int updateByPrimaryKeySelective(T record);
public int updateByPrimaryKey(T record);
public List<T> selectListByPage(T record);
public int deleteByPrimaryKey(Object o);
public int delete(T t);
public boolean existsWithPrimaryKey(Object o);
public T selectByPrimaryKey(Object o);
public T selectOne(T t);
public int deleteByIds(String s);
public int insertList(List<T> list);
public int insertUseGeneratedKeys(T t);
public int deleteByExample(Object o);
public List<T> selectByExample(Object o);
public int selectCountByExample(Object o);
public T selectOneByExample(Object o);
public int updateByExample(T t, Object o);
public int updateByExampleSelective(T t, Object o);
public List<T> selectByExampleAndRowBounds(Object o, RowBounds rowBounds);
public List<T> selectByRowBounds(T t, RowBounds rowBounds);
List<T> selectListByPage(T record);*/
public ReType show(T t, int page, int limit);

View File

@ -11,11 +11,14 @@ public class CustomUsernamePasswordToken extends UsernamePasswordToken {
private String type;
public CustomUsernamePasswordToken(final String username, final String password, String loginType) {
super(username,password);
this.type = loginType;
}
public String getType() {
return type;
}

View File

@ -7,6 +7,7 @@ import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Date;
import java.util.List;
public class JWTUtil {
@ -34,8 +35,6 @@ public class JWTUtil {
}
/**
* 获得token中的信息无需secret解密也能获得
*
* @return token中包含的用户名
*/
public static String getUsername(String token) {
@ -47,6 +46,21 @@ public class JWTUtil {
}
}
/**
* 获取角色组
*
* @param token
* @return
*/
public static String[] getRoles(String token) {
try {
DecodedJWT jwt = JWT.decode(token);
return jwt.getClaim("roles").asArray(String.class);
} catch (JWTDecodeException e) {
return null;
}
}
/**
* 生成签名,5min后过期
*
@ -54,12 +68,16 @@ public class JWTUtil {
* @param secret 用户的密码
* @return 加密的token
*/
public static String sign(String username, String secret) {
public static String sign(String username, List<String> roles, String secret) {
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
Algorithm algorithm = Algorithm.HMAC256(secret);
String[] roleArr = new String[roles.size()];
roleArr = roles.toArray(roleArr);
// 附带username信息
return JWT.create()
.withClaim("username", username)
// .withClaim("roles", role)
.withArrayClaim("roles", roleArr)
.withExpiresAt(date)
.sign(algorithm);
}

View File

@ -2,6 +2,7 @@ package com.len.util;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
/**
* @author zhuxiaomeng
@ -9,51 +10,45 @@ import com.alibaba.fastjson.JSONObject;
* @email 154040976@qq.com
* ajax 回执
*/
@Data
public class JsonUtil {
//默认成功
private boolean flag=true;
private String msg;
private JSONObject josnObj;
//默认成功
private boolean flag = true;
private String msg;
private JSONObject josnObj;
private Integer status;
public boolean isFlag() {
return flag;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public String getMsg() {
return msg;
}
public JsonUtil() {
}
public void setMsg(String msg) {
this.msg = msg;
}
public JsonUtil(boolean flag, String msg) {
this.flag = flag;
this.msg = msg;
}
public JSONObject getJosnObj() {
return josnObj;
}
public JsonUtil(boolean flag, String msg, Integer status) {
this.flag = flag;
this.msg = msg;
this.status = status;
}
public void setJosnObj(JSONObject josnObj) {
this.josnObj = josnObj;
}
/**
* restful 返回
*/
public static JsonUtil error(String msg) {
return new JsonUtil(false, msg);
}
public JsonUtil() {
}
public JsonUtil(boolean flag, String msg) {
this.flag = flag;
this.msg = msg;
}
/**restful 返回*/
public static JsonUtil error(String msg){
return new JsonUtil(false,msg);
}
public static JsonUtil sucess(String msg){
return new JsonUtil(true,msg);
}
public static JsonUtil sucess(String msg) {
return new JsonUtil(true, msg);
}
}

View File

@ -0,0 +1,45 @@
package com.len.util;
import org.apache.shiro.authc.AuthenticationToken;
/**
* @author zhuxiaomeng
* @date 2018/8/19.
* @email 154040976@qq.com
*/
public class JwtToken implements AuthenticationToken {
private String token;
private String type;
public JwtToken(String token,String type) {
this.token = token;
this.type=type;
}
@Override
public Object getPrincipal() {
return token;
}
@Override
public Object getCredentials() {
return token;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

View File

@ -109,34 +109,6 @@ public class LoginController {
return "/login";
}
@ApiOperation(value = "/blogLogin", httpMethod = "POST", notes = "登录method")
@PostMapping(value = "/blogLogin")
public String blogLogin(SysUser user, Model model, String rememberMe, HttpServletRequest request) {
/*String codeMsg = (String) request.getAttribute("shiroLoginFailure");
if ("code.error".equals(codeMsg)) {
model.addAttribute("message", "验证码错误");
return "/login";
}*/
CustomUsernamePasswordToken token = new CustomUsernamePasswordToken(user.getUsername().trim(),
user.getPassword(), "BlogLogin");
Subject subject = ShiroUtil.getSubject();
String msg = null;
try {
subject.login(token);
if (subject.isAuthenticated()) {
return "redirect:/main";
}
} catch (UnknownAccountException | IncorrectCredentialsException e) {
msg = "用户名/密码错误";
} catch (ExcessiveAttemptsException e) {
msg = "登录失败多次账户锁定10分钟";
}
if (msg != null) {
model.addAttribute("message", msg);
}
return "/login";
}
@GetMapping("/main")
public String main() {
return "main/main";

View File

@ -1,128 +0,0 @@
package com.len.core.shiro;
import com.alibaba.fastjson.JSONArray;
import com.len.base.CurrentMenu;
import com.len.base.CurrentRole;
import com.len.base.CurrentUser;
import com.len.entity.SysMenu;
import com.len.entity.SysRole;
import com.len.entity.SysUser;
import com.len.service.MenuService;
import com.len.service.RoleMenuService;
import com.len.service.RoleUserService;
import com.len.service.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
/**
* @author zhuxiaomeng
* @date 2017/12/4.
* @email 154040976@qq.com
*/
@Service
public class BlogRealm extends AuthorizingRealm {
@Autowired
private SysUserService userService;
@Autowired
private MenuService menuService;
@Autowired
private RoleUserService roleUserService;
@Autowired
private RoleMenuService roleMenuService;
/* @Override
public boolean supports(AuthenticationToken token) {
return super.supports(token);
}*/
/**
* 获取认证
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
String name= (String) principalCollection.getPrimaryPrincipal();
//根据用户获取角色 根据角色获取所有按钮权限
CurrentUser cUser= (CurrentUser) ShiroUtil.getSession().getAttribute("curentUser");
for(CurrentRole cRole:cUser.getCurrentRoleList()){
info.addRole(cRole.getId());
}
for(CurrentMenu cMenu:cUser.getCurrentMenuList()){
if(!StringUtils.isEmpty(cMenu.getPermission()))
info.addStringPermission(cMenu.getPermission());
}
return info;
}
/**
* 获取授权
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;
String name=upToken.getUsername();
String username=(String)authenticationToken.getPrincipal();
SysUser s=null;
try {
s = userService.login(username);
}catch (Exception e){
e.printStackTrace();
}
if(s==null){
throw new UnknownAccountException("账户密码不正确");
}else{
CurrentUser currentUser=new CurrentUser(s.getId(),s.getUsername(),s.getAge(),s.getEmail(),s.getPhoto(),s.getRealName());
Subject subject = ShiroUtil.getSubject();
/**角色权限封装进去*/
//根据用户获取菜单
List<SysMenu> menuList=new ArrayList<>(new HashSet<>(menuService.getUserMenu(s.getId())));
JSONArray json=menuService.getMenuJsonByUser(menuList);
Session session= subject.getSession();
session.setAttribute("menu",json);
CurrentMenu currentMenu=null;
List<CurrentMenu> currentMenuList=new ArrayList<>();
List<SysRole> roleList=new ArrayList<>();
for(SysMenu m:menuList){
currentMenu=new CurrentMenu(m.getId(),m.getName(),m.getPId(),m.getUrl(),m.getOrderNum(),m.getIcon(),m.getPermission(),m.getMenuType(),m.getNum());
currentMenuList.add(currentMenu);
roleList.addAll(m.getRoleList());
}
roleList= new ArrayList<>(new HashSet<>(roleList));
List<CurrentRole> currentRoleList=new ArrayList<>();
CurrentRole role=null;
for(SysRole r:roleList){
role=new CurrentRole(r.getId(),r.getRoleName(),r.getRemark());
currentRoleList.add(role);
}
currentUser.setCurrentRoleList(currentRoleList);
currentUser.setCurrentMenuList(currentMenuList);
session.setAttribute("curentUser",currentUser);
}
ByteSource byteSource=ByteSource.Util.bytes(username);
return new SimpleAuthenticationInfo(username,s.getPassword(), byteSource, getName());
}
}

View File

@ -11,21 +11,12 @@ import com.len.service.MenuService;
import com.len.service.RoleMenuService;
import com.len.service.RoleUserService;
import com.len.service.SysUserService;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import com.len.util.JWTUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
@ -33,101 +24,115 @@ import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author zhuxiaomeng
* @date 2017/12/4.
* @email 154040976@qq.com
*/
@Service
public class LoginRealm extends AuthorizingRealm {
public class LoginRealm extends AuthorizingRealm {
@Autowired
private SysUserService userService;
@Autowired
private SysUserService userService;
@Autowired
private MenuService menuService;
@Autowired
private MenuService menuService;
@Autowired
private RoleUserService roleUserService;
@Autowired
private RoleUserService roleUserService;
@Autowired
private RoleMenuService roleMenuService;
@Autowired
private RoleMenuService roleMenuService;
/* @Override
public boolean supports(AuthenticationToken token) {
return super.supports(token);
}*/
/**
* 获取认证
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
String name= (String) principalCollection.getPrimaryPrincipal();
//根据用户获取角色 根据角色获取所有按钮权限
CurrentUser cUser= (CurrentUser) ShiroUtil.getSession().getAttribute("curentUser");
for(CurrentRole cRole:cUser.getCurrentRoleList()){
info.addRole(cRole.getId());
}
for(CurrentMenu cMenu:cUser.getCurrentMenuList()){
if(!StringUtils.isEmpty(cMenu.getPermission()))
info.addStringPermission(cMenu.getPermission());
}
return info;
}
/**
* 获取授权
*
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
String name = (String) principalCollection.getPrimaryPrincipal();
Set<String> realmNames = principalCollection.getRealmNames();
List<String> realmNameList = new ArrayList<>(realmNames);
if ("BlogLogin".equals(realmNameList.get(0))) {
String[] roles = JWTUtil.getRoles(name);
assert roles != null;
for (String role : roles) {
info.addRole(role);
}
} else {
//根据用户获取角色 根据角色获取所有按钮权限
CurrentUser cUser = (CurrentUser) ShiroUtil.getSession().getAttribute("curentUser");
for (CurrentRole cRole : cUser.getCurrentRoleList()) {
info.addRole(cRole.getId());
}
for (CurrentMenu cMenu : cUser.getCurrentMenuList()) {
if (!StringUtils.isEmpty(cMenu.getPermission())){
info.addStringPermission(cMenu.getPermission());
}
}
}
/**
* 获取授权
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;
String name=upToken.getUsername();
String username=(String)authenticationToken.getPrincipal();
SysUser s=null;
try {
s = userService.login(username);
}catch (Exception e){
e.printStackTrace();
return info;
}
if(s==null){
throw new UnknownAccountException("账户密码不正确");
}else{
CurrentUser currentUser=new CurrentUser(s.getId(),s.getUsername(),s.getAge(),s.getEmail(),s.getPhoto(),s.getRealName());
Subject subject = ShiroUtil.getSubject();
/**角色权限封装进去*/
//根据用户获取菜单
List<SysMenu> menuList=new ArrayList<>(new HashSet<>(menuService.getUserMenu(s.getId())));
JSONArray json=menuService.getMenuJsonByUser(menuList);
Session session= subject.getSession();
session.setAttribute("menu",json);
CurrentMenu currentMenu=null;
List<CurrentMenu> currentMenuList=new ArrayList<>();
List<SysRole> roleList=new ArrayList<>();
for(SysMenu m:menuList){
currentMenu=new CurrentMenu(m.getId(),m.getName(),m.getPId(),m.getUrl(),m.getOrderNum(),m.getIcon(),m.getPermission(),m.getMenuType(),m.getNum());
currentMenuList.add(currentMenu);
roleList.addAll(m.getRoleList());
}
roleList= new ArrayList<>(new HashSet<>(roleList));
List<CurrentRole> currentRoleList=new ArrayList<>();
CurrentRole role=null;
for(SysRole r:roleList){
role=new CurrentRole(r.getId(),r.getRoleName(),r.getRemark());
currentRoleList.add(role);
}
currentUser.setCurrentRoleList(currentRoleList);
currentUser.setCurrentMenuList(currentMenuList);
session.setAttribute("curentUser",currentUser);
/**
* 获取认证
*
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;
String username = (String) authenticationToken.getPrincipal();
SysUser s = null;
try {
s = userService.login(username);
} catch (Exception e) {
e.printStackTrace();
}
if (s == null) {
throw new UnknownAccountException("账户密码不正确");
} else {
CurrentUser currentUser = new CurrentUser(s.getId(), s.getUsername(), s.getAge(), s.getEmail(), s.getPhoto(), s.getRealName());
Subject subject = ShiroUtil.getSubject();
/**角色权限封装进去*/
//根据用户获取菜单
List<SysMenu> menuList = new ArrayList<>(new HashSet<>(menuService.getUserMenu(s.getId())));
JSONArray json = menuService.getMenuJsonByUser(menuList);
Session session = subject.getSession();
session.setAttribute("menu", json);
CurrentMenu currentMenu = null;
List<CurrentMenu> currentMenuList = new ArrayList<>();
List<SysRole> roleList = new ArrayList<>();
for (SysMenu m : menuList) {
currentMenu = new CurrentMenu(m.getId(), m.getName(), m.getPId(), m.getUrl(), m.getOrderNum(), m.getIcon(), m.getPermission(), m.getMenuType(), m.getNum());
currentMenuList.add(currentMenu);
roleList.addAll(m.getRoleList());
}
roleList = new ArrayList<>(new HashSet<>(roleList));
List<CurrentRole> currentRoleList = new ArrayList<>();
CurrentRole role = null;
for (SysRole r : roleList) {
role = new CurrentRole(r.getId(), r.getRoleName(), r.getRemark());
currentRoleList.add(role);
}
currentUser.setCurrentRoleList(currentRoleList);
currentUser.setCurrentMenuList(currentMenuList);
session.setAttribute("curentUser", currentUser);
}
ByteSource byteSource = ByteSource.Util.bytes(username);
return new SimpleAuthenticationInfo(username, s.getPassword(), byteSource, getName());
}
ByteSource byteSource=ByteSource.Util.bytes(username);
return new SimpleAuthenticationInfo(username,s.getPassword(), byteSource, getName());
}
}

View File

@ -12,6 +12,7 @@ import java.util.List;
public interface RoleService extends BaseService<SysRole,String> {
@Override
int deleteByPrimaryKey(String id);
@Override

View File

@ -13,6 +13,7 @@ public interface RoleUserService extends BaseService<SysRoleUser,String>{
int deleteByPrimaryKey(SysRoleUser sysRoleUser);
@Override
int insert(SysRoleUser sysRoleUser);
int selectCountByCondition(SysRoleUser sysRoleUser);

View File

@ -47,6 +47,7 @@ public interface SysUserService extends BaseService<SysUser,String> {
int checkUser(String username);
@Override
int updateByPrimaryKey(SysUser sysUser);

View File

@ -1,12 +1,13 @@
package com.len.config;
import com.len.util.CustomUsernamePasswordToken;
import com.len.util.JwtToken;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.realm.Realm;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.Collection;
@ -19,11 +20,24 @@ import java.util.Collection;
*/
public class MyModularRealmAuthenticator extends ModularRealmAuthenticator {
@Override
protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
assertRealmsConfigured();
CustomUsernamePasswordToken token = (CustomUsernamePasswordToken) authenticationToken;
String type = token.getType();
String type;
AuthenticationToken token;
if (authenticationToken instanceof JwtToken) {
JwtToken token1 = (JwtToken) authenticationToken;
token = token1;
type = token1.getType();
} else {
CustomUsernamePasswordToken token1 = (CustomUsernamePasswordToken) authenticationToken;
token = token1;
type = token1.getType();
}
if (StringUtils.isEmpty(type)) {
throw new RuntimeException("登录认证授权类型不能为空");
}
Collection<Realm> realms = getRealms();
Collection<Realm> realmsList = new ArrayList<>();
for (Realm realm : realms) {
@ -34,4 +48,6 @@ public class MyModularRealmAuthenticator extends ModularRealmAuthenticator {
return realmsList.size() == 1 ? doSingleRealmAuthentication(realmsList.iterator().next(), token)
: doMultiRealmAuthentication(realmsList, token);
}
}

View File

@ -1,8 +1,9 @@
package com.len.config;
import com.len.core.BlogRealm;
import com.len.core.MyBasicHttpAuthenticationFilter;
import com.len.core.filter.PermissionFilter;
import com.len.core.filter.VerfityCodeFilter;
import com.len.core.shiro.BlogRealm;
import com.len.core.shiro.LoginRealm;
import com.len.core.shiro.RetryLimitCredentialsMatcher;
import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
@ -26,135 +27,152 @@ import java.util.*;
* @author zhuxiaomeng
* @date 2018/1/1.
* @email 154040976@qq.com
*spring shiro
* spring shiro
* 元旦快乐code everybody
*/
@Configuration
public class ShiroConfig {
@Bean
public RetryLimitCredentialsMatcher getRetryLimitCredentialsMatcher(){
@Bean
public RetryLimitCredentialsMatcher getRetryLimitCredentialsMatcher() {
// RetryLimitCredentialsMatcher rm = new RetryLimitCredentialsMatcher(getCacheManager(),2);
RetryLimitCredentialsMatcher rm = new RetryLimitCredentialsMatcher(getCacheManager());
rm.setHashAlgorithmName("md5");
rm.setHashIterations(4);
return rm;
RetryLimitCredentialsMatcher rm = new RetryLimitCredentialsMatcher(getCacheManager());
rm.setHashAlgorithmName("md5");
rm.setHashIterations(4);
return rm;
}
@Bean(name = "userLoginRealm")
public LoginRealm getLoginRealm(){
LoginRealm realm= new LoginRealm();
realm.setCredentialsMatcher(getRetryLimitCredentialsMatcher());
return realm;
}
@Bean(name = "blogLoginRealm")
public BlogRealm blogLoginRealm(){
BlogRealm realm= new BlogRealm();
realm.setCredentialsMatcher(getRetryLimitCredentialsMatcher());
return realm;
}
}
@Bean
public EhCacheManager getCacheManager(){
EhCacheManager ehCacheManager=new EhCacheManager();
ehCacheManager.setCacheManagerConfigFile("classpath:ehcache/ehcache.xml");
return ehCacheManager;
}
/* @Bean
public BlogRetryLimitCredentialsMatcher getBlogRetryLimitCredentialsMatcher() {
BlogRetryLimitCredentialsMatcher rm = new BlogRetryLimitCredentialsMatcher(getCacheManager());
rm.setHashAlgorithmName("md5");
rm.setHashIterations(4);
return rm;
@Bean
public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
}*/
@Bean
public AtLeastOneSuccessfulStrategy getAtLeastOneSuccessfulStrategy(){
AtLeastOneSuccessfulStrategy strategy=new AtLeastOneSuccessfulStrategy();
return strategy;
}
@Bean
public MyModularRealmAuthenticator getMyModularRealmAuthenticator(){
MyModularRealmAuthenticator authenticator=new MyModularRealmAuthenticator();
authenticator.setAuthenticationStrategy(getAtLeastOneSuccessfulStrategy());
return authenticator;
}
@Bean(name="securityManager")
public SecurityManager getSecurityManager(@Qualifier("userLoginRealm") LoginRealm loginRealm,
@Qualifier("blogLoginRealm") BlogRealm blogLoginRealm){
DefaultWebSecurityManager dwm=new DefaultWebSecurityManager();
List<Realm> loginRealms=new ArrayList<>();
dwm.setAuthenticator(getMyModularRealmAuthenticator());
loginRealm.setName("UserLogin");
blogLoginRealm.setName("BlogLogin");
loginRealms.add(loginRealm);
loginRealms.add(blogLoginRealm);
dwm.setRealms(loginRealms);
dwm.setCacheManager(getCacheManager());
dwm.setSessionManager(defaultWebSessionManager());
return dwm;
}
@Bean(name = "userLoginRealm")
public LoginRealm getLoginRealm() {
LoginRealm realm = new LoginRealm();
realm.setCredentialsMatcher(getRetryLimitCredentialsMatcher());
return realm;
}
@Bean
public PermissionFilter getPermissionFilter(){
PermissionFilter pf=new PermissionFilter();
return pf;
}
@Bean(name = "blogLoginRealm")
public BlogRealm blogLoginRealm() {
return new BlogRealm();
}
@Bean
public VerfityCodeFilter getVerfityCodeFilter(){
VerfityCodeFilter vf= new VerfityCodeFilter();
vf.setFailureKeyAttribute("shiroLoginFailure");
vf.setJcaptchaParam("code");
vf.setVerfitiCode(true);
return vf;
}
@Bean
public EhCacheManager getCacheManager() {
EhCacheManager ehCacheManager = new EhCacheManager();
ehCacheManager.setCacheManagerConfigFile("classpath:ehcache/ehcache.xml");
return ehCacheManager;
}
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") SecurityManager securityManager){
ShiroFilterFactoryBean sfb = new ShiroFilterFactoryBean();
sfb.setSecurityManager(securityManager);
sfb.setLoginUrl("/login");
sfb.setUnauthorizedUrl("/goLogin");
Map<String, Filter> filters=new HashMap<>();
filters.put("per",getPermissionFilter());
filters.put("verCode",getVerfityCodeFilter());
sfb.setFilters(filters);
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/login","verCode,anon");
filterMap.put("/blogLogin","verCode,anon");
//filterMap.put("/login","anon");
filterMap.put("/getCode","anon");
filterMap.put("/blog/**","anon");
filterMap.put("/logout","logout");
filterMap.put("/plugin/**","anon");
filterMap.put("/user/**","per");
filterMap.put("/**","authc");
sfb.setFilterChainDefinitionMap(filterMap);
return sfb;
}
@Bean
public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
@Bean
public AtLeastOneSuccessfulStrategy getAtLeastOneSuccessfulStrategy() {
return new AtLeastOneSuccessfulStrategy();
}
@Bean
public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager){
AuthorizationAttributeSourceAdvisor as=new AuthorizationAttributeSourceAdvisor();
as.setSecurityManager(securityManager);
return as;
}
@Bean
public DefaultWebSessionManager defaultWebSessionManager() {
DefaultWebSessionManager defaultWebSessionManager = new DefaultWebSessionManager();
defaultWebSessionManager.setSessionIdCookieEnabled(true);
defaultWebSessionManager.setGlobalSessionTimeout(21600000);
defaultWebSessionManager.setDeleteInvalidSessions(true);
defaultWebSessionManager.setSessionValidationSchedulerEnabled(true);
defaultWebSessionManager.setSessionIdUrlRewritingEnabled(false);
return defaultWebSessionManager;
}
@Bean
public MyModularRealmAuthenticator getMyModularRealmAuthenticator() {
MyModularRealmAuthenticator authenticator = new MyModularRealmAuthenticator();
authenticator.setAuthenticationStrategy(getAtLeastOneSuccessfulStrategy());
return authenticator;
}
@Bean(name = "securityManager")
public SecurityManager getSecurityManager(@Qualifier("userLoginRealm") LoginRealm loginRealm,
@Qualifier("blogLoginRealm") BlogRealm blogLoginRealm) {
DefaultWebSecurityManager dwm = new DefaultWebSecurityManager();
List<Realm> loginRealms = new ArrayList<>();
dwm.setAuthenticator(getMyModularRealmAuthenticator());
loginRealm.setName("UserLogin");
blogLoginRealm.setName("BlogLogin");
loginRealms.add(loginRealm);
loginRealms.add(blogLoginRealm);
dwm.setRealms(loginRealms);
dwm.setCacheManager(getCacheManager());
dwm.setSessionManager(defaultWebSessionManager());
return dwm;
}
@Bean
public PermissionFilter getPermissionFilter() {
return new PermissionFilter();
}
@Bean
public MyBasicHttpAuthenticationFilter getAuthenticationFilter() {
return new MyBasicHttpAuthenticationFilter();
}
@Bean
public VerfityCodeFilter getVerfityCodeFilter() {
VerfityCodeFilter vf = new VerfityCodeFilter();
vf.setFailureKeyAttribute("shiroLoginFailure");
vf.setJcaptchaParam("code");
vf.setVerfitiCode(true);
return vf;
}
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") SecurityManager securityManager) {
ShiroFilterFactoryBean sfb = new ShiroFilterFactoryBean();
sfb.setSecurityManager(securityManager);
sfb.setLoginUrl("/login");
sfb.setUnauthorizedUrl("/goLogin");
Map<String, Filter> filters = new HashMap<>();
filters.put("per", getPermissionFilter());
filters.put("verCode", getVerfityCodeFilter());
filters.put("jwt", getAuthenticationFilter());
sfb.setFilters(filters);
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/login", "verCode,anon");
filterMap.put("/blogLogin", "verCode,anon");
//filterMap.put("/login","anon");
filterMap.put("/getCode", "anon");
// filterMap.put("/blog/**", "anon");
filterMap.put("/logout", "logout");
filterMap.put("/plugin/**", "anon");
filterMap.put("/user/**", "per");
filterMap.put("/blog/**", "jwt");
filterMap.put("/**", "authc");
sfb.setFilterChainDefinitionMap(filterMap);
return sfb;
}
@Bean
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
@Bean
public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor as = new AuthorizationAttributeSourceAdvisor();
as.setSecurityManager(securityManager);
return as;
}
@Bean
public DefaultWebSessionManager defaultWebSessionManager() {
DefaultWebSessionManager defaultWebSessionManager = new DefaultWebSessionManager();
defaultWebSessionManager.setSessionIdCookieEnabled(true);
defaultWebSessionManager.setGlobalSessionTimeout(21600000);
defaultWebSessionManager.setDeleteInvalidSessions(true);
defaultWebSessionManager.setSessionValidationSchedulerEnabled(true);
defaultWebSessionManager.setSessionIdUrlRewritingEnabled(false);
return defaultWebSessionManager;
}
/*
@Bean
public FilterRegistrationBean delegatingFilterProxy(){