shiro-登录授权会话的简单使用demo

刚刚学习shiro,动手做了个入门demo,高手请绕道。嘻嘻

项目源码:https://github.com/cenmen/shiro-demo1.0.git

项目结构如下图:

在shiro数据库中新建两个表user和authority,表的内容如下图:

备注:demo使用springboot+ssm框架,在项目结构中的beans,mapper,service,service.impl包中的代码我就不贴出来了,也就是对数据库操作的代码,想要的可以自行下载源码看哦。

1,在pom.xml中引入shiro

<dependency>
	<groupId>org.apache.shiro</groupId>
	<artifactId>shiro-spring</artifactId>
	<version>1.2.3</version>
</dependency>

2,配置ShiroConfiguration类

package com.liang.auth;

import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.shiro.mgt.SecurityManager;


@Configuration
public class ShiroConfiguration {
	
	/*
		<bean id="userRealm" class="org.gec.smart.auth.UserRealm"/>
	*/
	@Bean
	public UserRealm userRealm() {
		return new UserRealm();
	}
	
	/*
		<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
			<property name="securityManager" ref="securityManager"/>
		</bean>
	*/
	@Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //指定认证失败后跳转的页面
        shiroFilterFactoryBean.setLoginUrl("/login.html");
        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/index.html");
        // 未授权界面;
        shiroFilterFactoryBean.setUnauthorizedUrl("/error.html");
        //配置资源的访问规则
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
        // 配置不会被拦截的链接 顺序判断,authc:所有url都必须认证通过才可以访问, anon:所有url都都可以匿名访问
        filterChainDefinitionMap.put("/login.html", "anon");
        filterChainDefinitionMap.put("/sys/login.do", "anon");
        //访问authority.html需要add权限
        filterChainDefinitionMap.put("/authority.html", "perms[add]");
        filterChainDefinitionMap.put("/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

	/*
		<bean id="securityManager" class="org.apache.shiro.mgt.SecurityManager">
			<property name="realm" value="userRealm">
		</bean>
	*/
    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm());
        return securityManager;
    } 

}

3,自定义Realm类:UserRealm

package com.liang.auth;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import com.liang.beans.Authority;
import com.liang.beans.User;
import com.liang.service.IUserService;

public class UserRealm extends AuthorizingRealm {
	@Autowired
	private IUserService userService;

	//执行授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		System.out.println("执行授权...");
		User token = (User)SecurityUtils.getSubject().getPrincipal();
		System.out.println(token);
	    String userRole = token.getRole();
	    SimpleAuthorizationInfo info =  new SimpleAuthorizationInfo();
	    //根据用户ID查询角色(role),放入到Authorization里。
	    Authority authority = userService.findAuthor(userRole);
	    Set<String> permissionSet = new HashSet<String>();
//	    String author = authority.getAuthor();
	    permissionSet.add(authority.getAuthor());
//	    info.setRoles(roleSet); //添加角色
	    info.setStringPermissions(permissionSet);
	    return info;
	}

	//执行认证
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg) throws AuthenticationException {
		System.out.println("执行认证......");
		UsernamePasswordToken token = (UsernamePasswordToken) arg;
		String password = new String(token.getPassword());
		User user = userService.findUsers(token.getUsername(), password);
		//如果该方法返回AuthenticationInfo对象就代表认证成功,如果返回null就代表认证失败
		if (user != null) { //登录成功
			return new SimpleAuthenticationInfo(
					user, //priciple,使用当前登录用户对象
					password,  //credentials
					user.getName()); //realmName
		}
		return null;  //返回null代表认证失败
	}
}

4,在Controller层操作:UserController

package com.liang.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.liang.beans.User;
import com.liang.service.IUserService;

@RestController //就是@Controlller和@ResponseBody注解的结合
@RequestMapping("/sys")
public class UserController {
	@Autowired
	private IUserService userService;

	@RequestMapping(path="/login.do", produces="application/json;charset=utf-8")
	public Map login(String username, String password) {
		Map map =new HashMap();
		//第一步:创建令牌
		UsernamePasswordToken token = new UsernamePasswordToken(username, password); //james , 234
		//第二步:获取Subject对象,该对象封装了一系列的操作
		Subject subject = SecurityUtils.getSubject();
		//第三步:执行认证
		try {
			subject.login(token);
			System.out.println("登录成功");
			map.put("status", "200");
			map.put("message", "登录成功");
			return map;
		} catch (AuthenticationException e) {
			e.printStackTrace();
			map.put("status", "500");
			map.put("message", "登录失败");
		}
		return map;

	}
	
	@RequestMapping(path="/logout.do", produces="application/json;charset=utf-8")
	public Map logout(HttpSession session) {
		//session.removeAttribute("user"); //删除Session的user属性
		//session.invalidate(); //把整个session销毁
		Map map =new HashMap();
		SecurityUtils.getSubject().logout();
		map.put("status", "200");
		map.put("message", "注销成功");
		return map;
	}
	
	@RequestMapping(path="/addSession.do", produces="application/json;charset=utf-8")
	public Map addSession(HttpSession session) {
		session.setAttribute("session", "session");
		Map map =new HashMap();
		try {
			userService.addSession();
			map.put("status", "200");
			map.put("message", "添加Session成功");
		} catch (Exception e) {
			e.printStackTrace();
			map.put("status", "500");
			map.put("message", "登录失败");
		}
		return map;
	}
}

5,login.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
<title>login</title>
<script>
function submit() {
	$.post("/sys/login.do", {
		username: $("input[name='username']").val(),
		password: $("input[name='password']").val()
		},function(data){
			if(data.status=='200'){
				$(location).attr('href', 'index.html');
				}else{
					alert(data.message+","+data.status);
				}
		    });
}
</script>
</head>
<body>
	<div>
		<input type="text" name="username">
		<input type="password" name="password">
		<button onclick="submit()">submit</button>
	</div>
</body>
</html>

其他html我就不贴了,大概都差不多,就是发送请求。

总结

  • ShiroConfiguration配置类,配置资源访问的规则,注入自定义的Realm类;
  • 在自定义Realm类中重写doGetAuthorizationInfo(授权)和doGetAuthenticationInfo(认证)方法。在登录时提交token,在后台利用token的get方法获取字段,然后可以进行数据库的查询,将返回的数据进行处理。
  • Session manager的使用,在Serivice层亦可以获取Session。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值