<dependency>
<groupId>org.apache.shirogroupId>
<artifactId>shiro-springartifactId>
<version>1.7.1version>
dependency>
ShiroConfig 和 UserRealm
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;
@Configuration
public class ShiroConfig {
//配置Shiro的三大对象
//三:ShiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
return bean;
}
//二:DefaultWebSecurityManager
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联 UserRealm 用spring容器中拿 参数传
securityManager.setRealm(userRealm);
return securityManager;
}
//一:创建realm对象,需自定义类
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
}
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.context.annotation.Configuration;
// 自定义的 UserRealm 需继承 AuthorizingRealm
public class UserRealm extends AuthorizingRealm {
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了授权");
return null;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行了认证");
return null;
}
}
在templates目录下新建user目录 下面新建两个页面
@Configuration
public class ShiroConfig {
//配置Shiro的三大对象
//三:ShiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//设置安全管理器。。。。。
/* 添加Shiro的内置过滤器
anon:无需认证即可访问
authc:必须认证了才能访问
user:必须拥有 记住我 功能才能用
perms:拥有对某个资源的权限才能访问
role:拥有某个角色权限才能访问
*/
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/user/*","authc");
bean.setFilterChainDefinitionMap(filterMap);
return bean;
}
效果如图所示
我们想要他 如果没有权限的话 跳转到 登陆页面 所以我们需要在设置过滤器的下面设置一个登陆请求
//设置登陆的请求
bean.setLoginUrl("/toLogin");
并在控制层 新添一个toLogin请求 编写一个login页面
//登陆
@GetMapping("/toLogin")
public String toLogin(){
return "/login";
}
既然要登陆验证 必然需要写一个登陆的请求
在controller中
//登陆
@GetMapping("/login")
public String login(String username,String password,Model model){
//获取当前用户
Subject subject = SecurityUtils.getSubject();
//封装用户的登陆数据
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);//执行登陆方法,如果没有异常 则成功登陆
return "index";
} catch (UnknownAccountException e) {//用户名不存在
e.printStackTrace();
model.addAttribute("msg","用户名错误");
return "login";
}catch (IncorrectCredentialsException e){//密码错误
e.printStackTrace();
model.addAttribute("msg","密码错误");
return "login";
}
}
login页面 也让他走这个请求
其实我们的认证 是在UserRealm中实现的
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行了认证");
//用户名,密码 暂时自己模拟
String name = "csnz";
String password = "123456";
UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
if(!token.getUsername().equals(name)){
return null;//直接抛出异常 UnknownAccountException
}
//密码验证,shiro 会做
return new SimpleAuthenticationInfo("",password,"");
}
虽然控制层和这个realm类看起来毫无关联 但是 走的请求却会来到realm类的认证方法中