第一步:重写Realm
import com.baizhi.entity.User; import org.apache.shiro.authc.*; import org.apache.shiro.realm.AuthenticatingRealm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Created by mhm on 2019/6/27. */
public class MyRealm extends AuthenticatingRealm { private Logger logger = LoggerFactory.getLogger(MyRealm.class); @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { UsernamePasswordToken upToken = (UsernamePasswordToken) token; //获取到用户输入的用户名
String username = upToken.getUsername(); //去数据库中查询,模拟
logger.info("开始从数据库中查询"); User user = new User(); user.setName("xiaobai"); user.setPassword("1"); // 把查询到的数据封装成AuthenticationInfo对象
/** * 参数1:principal 身份信息 账号 * 参数2:凭证信息 密码 * 参数3:realm的名字 */ SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user.getName(),user.getPassword(),this.getName()); logger.info("查询结束,返回结果"); return simpleAuthenticationInfo; } }
上面这个图,就是说为啥需要重写Realm,
第二步:配置
import com.baizhi.util.MyRealm; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.mgt.WebSecurityManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.HashMap; import java.util.Map; /** * Created by mhm on 2019/6/27. */
//声明,为配置类
@Configuration public class ShiroConfig { private Logger logger = LoggerFactory.getLogger(ShiroConfig.class); /** * 创建自定义的Realm */ @Bean public MyRealm getMyRealm(){ return new MyRealm(); } /** *创建安全管理器 */ @Bean//Bean注解修饰的方法的形参,在Spring创建时,从工厂中赋值
public WebSecurityManager getWebSecurityManager(MyRealm myRealm){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //设置自定义Realm
securityManager.setRealm(myRealm); return securityManager; } /** * 创建过滤器 */ @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(WebSecurityManager securityManager){ logger.info("创建Shiro过滤器"); ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean(); /** * 设置过滤规则 */ logger.info("设置过滤规则"); Map map = new HashMap(); /** * anon 代表匿名可访问 就是不用登录就可以访问 不过滤 * * authc 代表登录后才能访问 需要认证 会被过滤 * * 支持通配符* * * 注意拦截规则 一个一个配置 */ map.put("/login.jsp","anon"); map.put("/shiro/*","anon"); map.put("/main/*", "authc"); map.put("/guru/*", "authc"); map.put("/menu/*", "authc"); filterFactoryBean.setFilterChainDefinitionMap(map); /** * 配置没有登录,被拦截后的请求路径 */ filterFactoryBean.setLoginUrl("userLogin.jsp"); //设置安全管理器
logger.info("设置安全管理器"); filterFactoryBean.setSecurityManager(securityManager); return filterFactoryBean; } }
3.在Controller中使用
@RequestMapping("login") public @ResponseBody void login(String username,String password){ logger.info("开始登录"); //1.把数据封装成Token
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password); //2.获取Subject
Subject subject = SecurityUtils.getSubject(); //3.登录
try { subject.login(usernamePasswordToken); logger.info("登录成功"); } catch (AuthenticationException e) { // e.printStackTrace();
logger.info("登录失败"); } }
我这里就做一个模拟,不实际跳转了。