Customize Realm to achieve authentication

Customize Realm to achieve authentication

Shiro uses the built-in IniRealm by default. IniRealm reads user information from the ini configuration file. In most cases, you need to read user information from the system database, so you need to customize realm.



1. Realm interface

The most basic is the Realm interface, CachingRealm is responsible for cache processing, AuthenticatingRealm is responsible for authentication , AuthorizingRealm is responsible for authorization ,

Usually custom realm inherits AuthorizingRealm





 

shiro.ini

User.java

package com.sxt.domain;

import java.util.Date;

public class User {
	
	private Integer id;
	private String username;
	private String pwd;
	private Date createtime;
	public User() {
	}
	
	public User(Integer id, String username, String pwd, Date createtime) {
		super();
		this.id = id;
		this.username = username;
		this.pwd = pwd;
		this.createtime = createtime;
	}

	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	public Date getCreatetime() {
		return createtime;
	}
	public void setCreatetime(Date createtime) {
		this.createtime = createtime;
	}
}

UserService.java

package com.sxt.service;

import com.sxt.domain.User;

public interface UserService {
	
	/**
	 * 根据用户名查询用户对象
	 */
	public User queryUserByUserName(String username);

}

UserServiceImpl.java

package com.sxt.service.imp;

import java.util.Date;

import com.sxt.domain.User;
import com.sxt.service.UserService;

public class UserServiceImpl implements UserService {
	@Override
	public User queryUserByUserName(String username) {
		User user=null;
		switch (username) {
		case "zhangsan":
			user=new User(1, "zhangsan", "123456", new Date());
			break;
		case "lisi":
			user=new User(2, "lisi", "123456", new Date());
			break;
		case "wangwu":
			user=new User(3, "wangwu", "123456", new Date());
			break;
		}
		return user;
	}

}

UserRealm.java

package com.sxt.realm;

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.realm.AuthenticatingRealm;

import com.sxt.domain.User;
import com.sxt.service.UserService;
import com.sxt.service.imp.UserServiceImpl;

public class UserRealm extends AuthenticatingRealm {

	private UserService userService=new UserServiceImpl();
	/**
	 * 做认证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String username=token.getPrincipal().toString();
		token.getCredentials();
		System.out.println(username);
		/**
		 * 以前登陆的逻辑是  把用户和密码全部发到数据库  去匹配
		 * 在shiro里面是先根据用户名把用户对象查询出来,再来做密码匹配
		 */
		User user=userService.queryUserByUserName(username);
		if(null!=user) {
			/**
			 * 参数说明
			 * 参数1:可以传到任意对象
			 * 参数2:从数据库里面查询出来的密码
			 * 参数3:当前类名
			 */
			SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(user, user.getPwd(), this.getName());
			return info;
		}else {
			//用户不存在  shiro会抛 UnknowAccountException
			return null;
		}
	}

}

TestAuthenticationApp.java

package com.sxt.shiro;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * shiro的认证使用shiro.ini文件
 *
 */
@SuppressWarnings("deprecation")
public class TestAuthenticationApp {
	// 日志输出工具
	private static final transient Logger log = LoggerFactory.getLogger(TestAuthenticationApp.class);

	public static void main(String[] args) {

		String username = "zhangsan";
		String password = "123456";

		log.info("My First Apache Shiro Application");
		// 1,创建安全管理器的工厂对象 org.apache.shiro.mgt.SecurityManager;
		// 不能使用java.lang.SecurityManager
		Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
		// 2,使用工厂创建安全管理器
		DefaultSecurityManager securityManager = (DefaultSecurityManager) factory.getInstance();
		// 3,创建UserRealm
//		UserRealm realm = new UserRealm();
		// 4,给securityManager注入userRealm
//		securityManager.setRealm(realm);
		// 6,把当前的安全管理器绑定当到线的线程
		SecurityUtils.setSecurityManager(securityManager);
		// 7,使用SecurityUtils.getSubject得到主体对象
		Subject subject = SecurityUtils.getSubject();
		// 8,封装用户名和密码
		AuthenticationToken token = new UsernamePasswordToken(username, password);
		// 9,得到认证
		try {
			subject.login(token);
			System.out.println("认证通过");
			
			Object principal = subject.getPrincipal();
			System.out.println(principal);
		} catch (IncorrectCredentialsException e) {
			System.out.println("密码不正确");
		} catch (UnknownAccountException e) {
			System.out.println("用户名不存在");
		}

	}
}

Published 529 original articles · praised 115 · 90,000 views

Guess you like

Origin blog.csdn.net/qq_39368007/article/details/105596754