pom文件:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
整合主配置类:
//自定义shiro类
public class MyShiroRealm extends AuthorizingRealm {
@Autowired
private UserServiceImpl userService;
/**
* 授权控制
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
Subject subject = SecurityUtils.getSubject();
//这里的Principal是在登陆时创建SimpleAuthenticationInfo对象传入的第一个参数
String username = (String) subject.getPrincipal();
Set<String> roles = userService.getRolesByUsername(username);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setRoles(roles);
return info;
}
/**
* 登陆验证控制
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
String tokenUsername = token.getUsername();
//判断用户名是否存在,若不存在则返回null,shiro则会抛出用户找不到的异常
User user = userService.selectUserByUserName(tokenUsername);
if (user ==null){
return null;
}
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(tokenUsername, user.getPassword(), "");
return authenticationInfo;
}
}
//shiro主配置类
@Configuration
public class ShiroConfiguration {
//将自己的验证方式加入容器
@Bean
public MyShiroRealm myShiroRealm() {
MyShiroRealm myShiroRealm = new MyShiroRealm();
return myShiroRealm;
}
//权限管理,配置主要是Realm的管理认证
@Bean
public DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager manager=new DefaultWebSecurityManager();
manager.setRealm(myShiroRealm());
manager.setRememberMeManager(rememberMeManager());
return manager;
}
//Filter工厂,设置对应的过滤条件和跳转条件
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//此处用LinkedHashMap,保证有序
Map<String,String> map = new LinkedHashMap<>();
//登出
map.put("/logout","logout");
map.put("/admin", "roles[admin]");
map.put("/css/**", "anon");
map.put("/js/**", "anon");
map.put("/register", "anon");
//对所有用户认证
map.put("/**","authc");
//登录连接
shiroFilterFactoryBean.setLoginUrl("/login");
//登陆成功后要跳转的连接
shiroFilterFactoryBean.setSuccessUrl("/index");
//错误页面,授权不通过跳转
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
//加入注解的使用,不加入这个注解不生效
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
/**
* cookie对象;
* rememberMeCookie()方法是设置Cookie的生成模版,比如cookie的name,cookie的有效时间等等。
* @return
*/
@Bean
public SimpleCookie rememberMeCookie(){
//System.out.println("ShiroConfiguration.rememberMeCookie()");
//这个参数是cookie的名称,对应前端的checkbox的name = rememberMe
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
//<!-- 记住我cookie生效时间30天 ,单位秒;-->
simpleCookie.setMaxAge(259200);
return simpleCookie;
}
/**
* cookie管理对象;
* rememberMeManager()方法是生成rememberMe管理器,而且要将这个rememberMe管理器设置到securityManager中
* @return
*/
@Bean
public CookieRememberMeManager rememberMeManager(){
//System.out.println("ShiroConfiguration.rememberMeManager()");
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
//rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)
cookieRememberMeManager.setCipherKey(Base64.decode("2AvVhdsgUs0FSA3SDFAdag=="));
return cookieRememberMeManager;
}
/**
* 启用shiro的thymeleaf标签
* @return
*/
@Bean(name = "shiroDialect")
public ShiroDialect shiroDialect(){
return new ShiroDialect();
}
}
在controller中使用shiro:
@PostMapping("/login")
public String login(LoginUser loginUser,Model model) {
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(loginUser.getUsername(), loginUser.getPassword());
usernamePasswordToken.setRememberMe(loginUser.isRememberMe());
try {
//进行验证,这里可以捕获异常,然后返回对应信息
subject.login(usernamePasswordToken);
//用户不存在时的异常
}catch (UnknownAccountException e){
model.addAttribute("loginError", true);
model.addAttribute("errorMsg", "登陆失败,账号或者密码错误!");
return "login";
//密码错误的异常
}catch (IncorrectCredentialsException e){
model.addAttribute("loginError", true);
model.addAttribute("errorMsg", "登陆失败,账号或者密码错误!");
return "login";
}
//给主页的数据
model.addAttribute("name", loginUser.getUsername());
return "index";
}
shiro的一些thymeleaf标签:
<!-- 验证当前用户是否为“访客”,即未认证(包含未记住)的用户。 -->
<p shiro:guest="">Please <a href="login.html">login</a></p>
<!-- 认证通过或已记住的用户。 -->
<p shiro:user="">
Welcome back John! Not John? Click <a href="login.html">here</a> to login.
</p>
<!-- 已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在。 -->
<p shiro:authenticated="">
Hello, <span shiro:principal=""></span>, how are you today?
</p>
<a shiro:authenticated="" href="updateAccount.html">Update your contact information</a>
<!-- 输出当前用户信息,通常为登录帐号信息。 -->
<p>Hello, <shiro:principal/>, how are you today?</p>
<!-- 未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户。 -->
<p shiro:notAuthenticated="">
Please <a href="login.html">login</a> in order to update your credit card information.
</p>
<!-- 验证当前用户是否属于该角色。 -->
<a shiro:hasRole="admin" href="admin.html">Administer the system</a><!-- 拥有该角色 -->
<!-- 与hasRole标签逻辑相反,当用户不属于该角色时验证通过。 -->
<p shiro:lacksRole="developer"><!-- 没有该角色 -->
Sorry, you are not allowed to developer the system.
</p>
<!-- 验证当前用户是否属于以下所有角色。 -->
<p shiro:hasAllRoles="developer, 2"><!-- 角色与判断 -->
You are a developer and a admin.
</p>
<!-- 验证当前用户是否属于以下任意一个角色。 -->
<p shiro:hasAnyRoles="admin, vip, developer,1"><!-- 角色或判断 -->
You are a admin, vip, or developer.
</p>
<!--验证当前用户是否拥有指定权限。 -->
<a shiro:hasPermission="userInfo:add" href="createUser.html">添加用户</a><!-- 拥有权限 -->
<!-- 与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过。 -->
<p shiro:lacksPermission="userInfo:del"><!-- 没有权限 -->
Sorry, you are not allowed to delete user accounts.
</p>
<!-- 验证当前用户是否拥有以下所有角色。 -->
<p shiro:hasAllPermissions="userInfo:view, userInfo:add"><!-- 权限与判断 -->
You can see or add users.
</p>
<!-- 验证当前用户是否拥有以下任意一个权限。 -->
<p shiro:hasAnyPermissions="userInfo:view, userInfo:del"><!-- 权限或判断 -->
You can see or delete users.
</p>
<a shiro:hasPermission="pp" href="createUser.html">Create a new User</a>
shiro的内置过滤器: