表结构
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`pwd` varchar(255) DEFAULT NULL,
`salt` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
INSERT INTO `user` VALUES ('1', 'captain', '36c952642de254f1b1872f321686f6c5', 'aH/CDyeNFN3DyZ3EXINXSQ==');
DatabaseRealm 类
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.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import top.qingrang.pojo.User;
import top.qingrang.service.UserService;
public class DatabaseRealm extends AuthorizingRealm {
@Autowired
UserService userService;
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;
String name = upToken.getPrincipal().toString();
User user = userService.getUser(name);
String pwdInDB = user.getPwd();
String salt = user.getSalt();
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
name, pwdInDB, ByteSource.Util.bytes(salt), getName());
return authenticationInfo;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo s = new SimpleAuthorizationInfo();
return s;
}
}
Shiro 配置类
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
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 top.qingrang.realm.DatabaseRealm;
@Configuration
public class ShiroConfiguration {
@Bean
public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
return shiroFilterFactoryBean;
}
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(getDatabaseRealm());
return securityManager;
}
@Bean
public DatabaseRealm getDatabaseRealm() {
DatabaseRealm myShiroRealm = new DatabaseRealm();
myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return myShiroRealm;
}
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");
hashedCredentialsMatcher.setHashIterations(2);
return hashedCredentialsMatcher;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}
UserController - 注册,登录,注销
@GetMapping("/register")
public Object register() {
String name = "zs";
String pwd = "111";
String salt = new SecureRandomNumberGenerator().nextBytes().toString();
int times = 2;
String algorithmName = "md5";
String encodedPassword = new SimpleHash(algorithmName, pwd, salt, times).toString();
User user = new User();
user.setName(name);
user.setPwd(pwd);
user.setSalt(salt);
user.setPwd(encodedPassword);
userService.insUser(user);
return "register";
}
@PostMapping(value = "/login")
public int login(@RequestBody User user, HttpSession session) throws Exception {
String name = user.getName();
name = HtmlUtils.htmlEscape(name);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(name, user.getPwd());
try {
subject.login(token);
User u = userService.getUser();
session.setAttribute("user", u);
return 1;
} catch (AuthenticationException e) {
return 0;
}
}
@GetMapping("/logout")
public String logout() {
Subject subject = SecurityUtils.getSubject();
if (subject.isAuthenticated())
subject.logout();
return "logout";
}
配置登录拦截器
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
String[] publicPages = new String[]{
"login",
"register",
"/api/synDiary",
"/api/dairiesByNewYear"
};
String uri = httpServletRequest.getRequestURI();
HttpSession session = httpServletRequest.getSession();
String contextPath = session.getServletContext().getContextPath();
uri = StringUtils.remove(uri, contextPath + "/");
if (!containWith(uri, publicPages)) {
try {
Subject subject = SecurityUtils.getSubject();
if (!subject.isAuthenticated()) {
httpServletResponse.sendRedirect("login");
return false;
}
} catch (Exception e) {
System.out.println(uri + " - " + e.getMessage());
}
}
return true;
}
private boolean containWith(String uri, String[] publicPages) {
boolean result = false;
for (String pages : publicPages) {
if (uri.indexOf(pages) >= 0) {
result = true;
break;
}
}
return result;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}