Spring Boot 整合 Shiro 简单实现用户登陆认证
首先我用的是idea 使用idea自带的spring boot 插件创建的spring boot项目
我的目录结构中如下:
pom.xml :
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.4.0</version>
</dependency>
login.html:
我这边有个转接 页面text.html内容如下:
1.add.html
2.update.html
ShiroConfig.java内容:
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 java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
/**
* 创建ShiroFilerFactoryBean
*/
@Bean(name = "shiroFilterFactoryBean")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
/**
* 常用过滤器
* anon:无需登录(认证) 可以直接访问
* authc:必须登录才可以访问
* user:如果使用rememberMe的功能可以直接访问
* perms:该资源必须得到资源权限才可以访问
* role:该资源必须得到角色权限才可以访问
*/
//使用Shiro内置的过滤器(权限相关的拦截)
//修改默认登录页面
shiroFilterFactoryBean.setLoginUrl("/login");
Map<String,String> filterMap = new LinkedHashMap<>(); //为了保证数据的顺序LinkedHashMap
// 添加过滤器
filterMap.put("/stest",“anon”);
filterMap.put("/toLogin",“anon”);
filterMap.put("/*",“authc”);//所有user下的都需要过滤
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(securityManager);
return shiroFilterFactoryBean;
}
/**
* 创建DefaultWebSecurityManager
*/
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("realmConfig") RealmConfig realmConfig){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联realm
securityManager.setRealm(realmConfig);
return securityManager;
}
/**
* 创建Realm
*/
@Bean(name = "realmConfig")
public RealmConfig getRealm(){
return new RealmConfig();
}
}
RealmConfig.java内容:
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class RealmConfig extends AuthorizingRealm {
/**
* 执行授权逻辑
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行授权逻辑1");
return null;
}
/**
* 执行授权逻辑
* @param
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
System.out.println("执行授权逻辑");
//编写Shiro的认证逻辑 判断用户名密码 我这边没有连接数据库 而是简单的做啦下测试
String name = "admin";
String password = "852";
UsernamePasswordToken token = (UsernamePasswordToken)arg0;
System.out.println(token.getUsername());
System.out.println(name);
if (!token.getUsername().equals(name)){
//用户名不存在
return null; //shiro 底层会抛出UnknownAccountException
}
//判断密码 这里返回一个AuthenticationInfo的子类 password 是从数据库传过的面 shiro会自动去判断
return new SimpleAuthenticationInfo("",password,"");
}
}
ShiroController 内容:
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class ShiroController {
@RequestMapping("/login")
public String login(){
return "login";
}
@RequestMapping("/stest")
public String Stest(){
return "test";
}
@RequestMapping("/add")
public String add(){
return "/user/add";
}
@RequestMapping("/update")
public String update(){
return "/user/update";
}
@RequestMapping("/toLogin")
public String toLogin(String name, String password, Model model){
System.out.println("进来啦");
/**
* 使用 shiro编写认证操作
*
* 1.获取Subject
*/
// 1.获取Subject
Subject subject = SecurityUtils.getSubject();
// 2.封装用户数据
UsernamePasswordToken token = new UsernamePasswordToken(name,password);
try {
subject.login(token); //在这边认证其实是调用到RealmConfig 来做校验
return "redirect:/stest";
} catch (UnknownAccountException e) { //Shiro判断是否登录成功 抓取异常如果没有异常登录成功
// e.printStackTrace();
//Shiro 判断异常也是非常细腻 账号不存在 或者是密码错误
model.addAttribute("msg","账号不存在");
return "login";
}
catch (IncorrectCredentialsException e) { //Shiro判断是否登录成功 抓取异常如果没有异常登录成功
// e.printStackTrace();
//Shiro 判断异常也是非常细腻 账号不存在 或者是密码错误
model.addAttribute("msg","密码错误");
return "login";
}
}
}
登陆页面
登陆成功后可访问的页面: