- pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
- 密码校验规则
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
public class CredentialsMatcher extends SimpleCredentialsMatcher {
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
UsernamePasswordToken token1 = (UsernamePasswordToken)token;
String password = new String (token1.getPassword());
String dbPassWord = (String) info.getCredentials();
return this.equals(password,dbPassWord);
}
}
- shiro配置类
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.mgt.SecurityManager;
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.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
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;
@Configuration
public class ShiroConfiguration {
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager")SecurityManager securityManager) {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(securityManager);
LinkedHashMap<String, Filter> filterMap = new LinkedHashMap<>();
filterMap.put("authc", new AjaxPermissionsAuthorizationFilter());
bean.setFilters(filterMap);
LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/", "anon");
filterChainDefinitionMap.put("/static/**", "anon");
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/login_out", "anon");
filterChainDefinitionMap.put("/error", "anon");
filterChainDefinitionMap.put("/**", "authc");
bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return bean;
}
@Bean("securityManager")
public SecurityManager securityManager(@Qualifier("userRealm")UserRealm userRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm);
return securityManager;
}
@Bean(name = "userRealm")
public UserRealm userRealm(@Qualifier("credentialsMatcher") CredentialsMatcher matcher) {
UserRealm userRealm = new UserRealm();
userRealm.setCacheManager(new MemoryConstrainedCacheManager());
userRealm.setCredentialsMatcher(matcher);
return userRealm;
}
@Bean(name = "credentialsMatcher")
public CredentialsMatcher credentialsMatcher() {
return new CredentialsMatcher();
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager")SecurityManager securityManager ) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
@Bean
@DependsOn({"lifecycleBeanPostProcessor"})
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
creator.setProxyTargetClass(true);
return creator;
}
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
- 自定义Realm实现认证授权
@Slf4j
public class UserRealm extends AuthorizingRealm {
@Autowired
private SystemAdminService systemAdminService;
@Override
@SuppressWarnings("unchecked")
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SystemAdminVo user = (SystemAdminVo) principals.fromRealm(this.getClass().getName()).iterator().next();
SystemRole roles = user.getRoles();
Set<String> set = new HashSet<>();
if(null != roles){
Set<SystemPermission> permissionSet = roles.getPermissionList();
if(CollectionUtils.isNotEmpty(permissionSet)){
for(SystemPermission permission : permissionSet){
set.add(permission.getPermissionCode());
}
}
}
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermissions(set);
info.addRole(roles.getRoleName());
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken)authcToken;
String loginName = usernamePasswordToken.getUsername();
SystemAdminVo user = systemAdminService.getFindByLoginName(loginName);
if (user == null) {
throw new UnknownAccountException();
}
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user,user.getPassword(),this.getClass().getName());
return authenticationInfo;
}
}
- 对没有登录的请求进行拦截过滤
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import com.alibaba.fastjson.JSONObject;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
public class AjaxPermissionsAuthorizationFilter extends FormAuthenticationFilter {
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("code", ErrorEnum.E_1000.getErrorCode());
jsonObject.put("msg", ErrorEnum.E_1000.getErrorMsg());
PrintWriter out = null;
HttpServletResponse res = (HttpServletResponse) response;
try {
res.setCharacterEncoding("UTF-8");
res.setContentType("application/json");
out = response.getWriter();
out.println(jsonObject);
} catch (Exception e) {
} finally {
if (null != out) {
out.flush();
out.close();
}
}
return false;
}
@Bean
public FilterRegistrationBean registration(AjaxPermissionsAuthorizationFilter filter) {
FilterRegistrationBean registration = new FilterRegistrationBean(filter);
registration.setEnabled(false);
return registration;
}
}
- 错误枚举定义
public enum ErrorEnum {
E_1000("1000", "登陆已过期,请重新登陆");
private String errorCode;
private String errorMsg;
ErrorEnum(String errorCode, String errorMsg) {
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public String getErrorCode() {
return errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
}
- 接口
@GetMapping("/login")
public JsonObject login(@RequestParam String loginName, @RequestParam String password) {
UsernamePasswordToken token = new UsernamePasswordToken(loginName, password);
Subject subject = SecurityUtils.getSubject();
subject.login(token);
SystemAdminVo vo = (SystemAdminVo)subject.getPrincipal();
return "返回json对象";
}