package com.mlcp.config;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.mlcp.core.shiro.MyShiroRealm;
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shirFilter(org.apache.shiro.mgt.SecurityManager securityManager) {
System.out.println("ShiroConfiguration.shirFilter()");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//拦截器.
Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
// 配置不会被拦截的链接 顺序判断
filterChainDefinitionMap.put("/static/**", "anon");
filterChainDefinitionMap.put("/img/**", "anon");
filterChainDefinitionMap.put("/lib/**", "anon");
filterChainDefinitionMap.put("/login/**", "anon");
filterChainDefinitionMap.put("/maxgraph/**", "anon");
//开放登陆接口
filterChainDefinitionMap.put("/login", "anon");
//开放登陆接口
filterChainDefinitionMap.put("/register", "anon");
//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/logout", "logout");
//<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
//<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
//filterChainDefinitionMap.put("/**", "anon");
filterChainDefinitionMap.put("/**", "authc");
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/login/login.html");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/main/newMain.html");
//未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public MyShiroRealm myShiroRealm(){
MyShiroRealm myShiroRealm = new MyShiroRealm();
return myShiroRealm;
}
@Bean
public org.apache.shiro.mgt.SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager;
}
}
package com.mlcp.core.shiro;
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.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.mlcp.core.util.ShiroConstant;
import com.mlcp.module.user.model.User;
import com.mlcp.module.user.service.UserService;
public class MyShiroRealm extends AuthorizingRealm {
private final static Logger log = LoggerFactory.getLogger(MyShiroRealm.class);
@Autowired
private UserService userService;
// shiro的权限配置方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
log.info("权限配置-->doGetAuthorizationInfo");
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
log.info("----------------------------->" + principals.getPrimaryPrincipal());
User user = (User) principals.getPrimaryPrincipal();
/*for(Role role:user.getRoleList()){
authorizationInfo.addRole(role.getRole_name());
for(Function function:role.getFunctionList()){
authorizationInfo.addStringPermission(function.getPermission());
}
}*/
log.info("用户" + user.getUsername() + "具有的角色:" + authorizationInfo.getRoles());
log.info("用户" + user.getUsername() + "具有的权限:" + authorizationInfo.getStringPermissions());
return authorizationInfo;
}
//shiro的身份验证方法
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
log.info("正在验证身份...");
SimpleAuthenticationInfo info = null;
// 将token转换成UsernamePasswordToken
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
// 从转换后的token中获取用户名
String username = upToken.getUsername();
log.info("----->" + username);
// 查询数据库,得到用户
User user = userService.findUserByName(username);
if (user == null) {
throw new UnknownAccountException();
}
// 得到加密密码的盐值
ByteSource credentialsSalt = ByteSource.Util.bytes(user.getUsername());
log.info("加密密码的盐:" + credentialsSalt);
// 得到盐值加密后的密码:只用于方便数据库测试,后期不会用到。
Object md = new SimpleHash(ShiroConstant.ALGORITHMNAME, upToken.getPassword(), credentialsSalt,
ShiroConstant.HASHITERATIONS).toString();
//输入登录密码
upToken.setPassword(md.toString().toCharArray());
log.info("盐值加密后的密码:" + md);
info = new SimpleAuthenticationInfo(user, // 用户名
user.getPassword(), // 密码
credentialsSalt, // 加密的盐值
getName() // realm name
);
return info;
}
}
package com.mlcp.web;
import java.util.Date;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import com.mlcp.core.responseBean.ReplyInfo;
import com.mlcp.core.util.ShiroConstant;
import com.mlcp.module.role.module.Role;
import com.mlcp.module.role.service.RoleService;
import com.mlcp.module.user.model.User;
import com.mlcp.module.user.service.UserService;
@RestController
public class LoginController {
@Autowired
private UserService userService;
@Autowired
private RoleService roleService;
@PostMapping("/register")
public ReplyInfo register(HttpServletRequest req) {
ReplyInfo reply = new ReplyInfo();
String username = req.getParameter("username");
Long Usercount = userService.countByUsername(username);
if (Usercount > 0) {
reply.setMessege("用户名已存在");
return reply;
}
String email = req.getParameter("email");
Long emailCount = userService.countByEmail(email);
if (emailCount > 0) {
reply.setMessege("邮箱已存在");
return reply;
}
String userId=UUID.randomUUID().toString().replaceAll("_", "").replaceAll("-","").trim();
User user = new User();
user.setId(userId);
user.setUsername(username);
user.setEmail(email);
ByteSource credentialsSalt = ByteSource.Util.bytes(user.getUsername());
user.setSalt(credentialsSalt.toString());
String password = new SimpleHash(ShiroConstant.ALGORITHMNAME, req.getParameter("password"), credentialsSalt,
ShiroConstant.HASHITERATIONS).toString();
user.setPassword(password);
Role role = roleService.getNomalRole();
user.getRoles().add(role);
user.setInTime(new Date());
Boolean flag = userService.addUser(user);
return new ReplyInfo(flag, null);
}
@PostMapping("/login")
public ReplyInfo login( HttpServletRequest req) {
ReplyInfo replyInfo = new ReplyInfo();
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(req.getParameter("username"),
req.getParameter("password"));
Subject subject = SecurityUtils.getSubject();
try {
subject.login(usernamePasswordToken); // 完成登录
User user2 = (User) subject.getPrincipal();
req.getSession().setAttribute("user", user2);
replyInfo.setSuccess(true);
return replyInfo;
} catch (UnknownAccountException e) {
replyInfo.setMessege("账号不存在");
} catch (IncorrectCredentialsException e){
replyInfo.setMessege("用户名/密码错误");
}catch (Exception e){
replyInfo.setMessege("系统异常");
}
return replyInfo;// 返回登录页面
}
}
很基础的登陆拦截器。没有设置用户级别