老实说吧,小白应该用拦截器,先不用权限框架,但是不知道为什么,我感觉框架很强,
然后数据库是 加盐加密算法,加 salt 配合 md5, 因为帮亲戚写网页,框架原理什么的还不是很懂,调试这能用,先记在这,以后读源码,写项目再回这参考
配置类:
package com.ywfcake.demo.config;
import com.ywfcake.demo.pojo.ManagerRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @Author lyr
* @create 2020/2/25 13:02
*/
@Configuration
public class ShiroConfiguration {
/**
* 密码校验规则HashedCredentialsMatcher
* 这个类是为了对密码进行编码的 ,
* 防止密码在数据库里明码保存 , 当然在登陆认证的时候 ,
* 这个类也负责对form里输入的密码进行编码
* 处理认证匹配处理器:如果自定义需要实现继承HashedCredentialsMatcher
*/
@Bean("hashedCredentialsMatcher")
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
//指定加密方式为MD5
credentialsMatcher.setHashAlgorithmName("MD5");
//加密次数
credentialsMatcher.setHashIterations(1024);
credentialsMatcher.setStoredCredentialsHexEncoded(true);
return credentialsMatcher;
}
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager manager) {
ShiroFilterFactoryBean shiroFilterFactoryBean
= new ShiroFilterFactoryBean();
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(manager);
/**
* shiro内置 过滤器,可以过滤 url,实现权限拦截
* 常见过滤器:
* anon: 无需认证(登录)可以访问
* authc: 必须认证才可以访问
* user: 如果使用 remenberMe 的功能可以直接访问
* perms : 改资源必须有资源权限才可以访问
* role: 该资源必须得到角色权限才可以访问
*
*/
Map<String,String> map = new LinkedHashMap<>();
map.put("/lyr/manager/**","authc");
map.put("/lyr/manager/login","anon");
map.put("*.js","anon");
map.put("*.css","anon");
map.put("/js/**","anon");
map.put("/img/**","anon");
map.put("/img/code","anon");
//修改认证跳转的登录页面 --》 默认 login.jsp
//注意 请求全部要经过 controller 才能跳转到对应的页面
// shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setLoginUrl("/lyr/manager/login");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("managerRealm")ManagerRealm managerRealm)
{
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(managerRealm);
return securityManager;
}
@Bean(name = "managerRealm")
public ManagerRealm getRealm(){
return new ManagerRealm();
}
}
realm 类:
package com.ywfcake.demo.pojo;
import com.ywfcake.demo.code.LoginConst;
import com.ywfcake.demo.service.PersonalInfoService;
import com.ywfcake.demo.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationException;
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 java.util.HashSet;
import java.util.Set;
/**
* @Author lyr
* @create 2020/2/25 13:06
*/
@Slf4j
public class ManagerRealm extends AuthorizingRealm {
@Autowired
private PersonalInfoService service;
/**
* 授权入口
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
if (principalCollection==null) {
throw new AuthorizationException(LoginConst.LOGIN_FAIL.getContent());
}
PersonalInformation personalInformation = (PersonalInformation) principalCollection.getPrimaryPrincipal();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
Set<String> roles = new HashSet<>();
roles.add("admin");
info.setRoles(roles);
log.info("授权触发");
return info;
}
/**
* 认证逻辑
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected SimpleAuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
if(authenticationToken.getPrincipal()==null) {
return null;
}
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken)authenticationToken;
String password = String.valueOf(usernamePasswordToken.getPassword());
String name = usernamePasswordToken.getUsername();
PersonalInformation person = service.findByNameWithSalt(name);
log.info("person {}",person);
log.info("password: {}",password);
String pwd = StringUtil.password(password,person.getSalt());
log.info("pwd: {}",pwd);
if (!pwd.equals(person.getUserPassword())) {
return null;
}
log.info("正常--> ");
return new SimpleAuthenticationInfo("",password,person.getUserName());
}
}
login 页面:
/**
* 处理用户登录请求
* @param person 用户提交的信息
* @return
*/
@PostMapping("/lyr/manager/login")
public String forLogin(PersonalInformation person,HttpServletRequest request, @RequestParam("code") String code) {
String code2 = (String) request.getSession().getAttribute("code");
Subject subject = SecurityUtils.getSubject();
if(code!=null &&code.equalsIgnoreCase(code2))
{
log.warn("登录");
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(person.getUserName(), person.getUserPassword());
try{
log.info("shiro判断环境");
subject.login(usernamePasswordToken);
}catch (AuthenticationException e)
{
log.error(e.toString());
return "/manager/wrong";
}
return "/manager/success";
}
log.warn("有人登陆错误了");
return "/manager/wrong";
}