认证-自定义Realm

ini

[main]
userRealm=cn.wit.realm.UserRealm
securityManager.realm=$userRealm

根据taken拿到username,然后用username查询数据库,返回User
对象信息,赋值username和password,SimpleAuthenticationInfo对象 传入username、password、realm名称(父类提供了getName方法,重写这个方法),然后返回这个info对象。表示将数据库的用户信息给shiro,shiro会去比较登录的信息(taken里边的),如果一致就登录成功

UserRealm extends AuthorizingRealm

package cn.wit.realm;

import java.beans.PropertyVetoException;
import java.sql.ResultSet;
import java.sql.SQLException;

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.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import cn.wit.users.Users;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;

public class UserRealm extends AuthorizingRealm{
    
    
	@Override
	public String getName() {
    
    
		// TODO Auto-generated method stub
		return "uesrRealm";
	}
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
    
    
		return null;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken taken) throws AuthenticationException {
    
    
			String username=(String) taken.getPrincipal();
			String pwd="";
		
			Connection conn=null;
	        PreparedStatement ps=null;
	        ResultSet rs=null;
	        ComboPooledDataSource cpds=null;
	        try {
    
    
	          //c3p0获取数据库连接conn
	    		cpds= new ComboPooledDataSource();
	    		cpds.setDriverClass("com.mysql.jdbc.Driver");
	    		cpds.setJdbcUrl("jdbc:mysql://localhost:3306/login");
	    		cpds.setUser("root");
	    		cpds.setPassword("wityy");
	    		conn = cpds.getConnection();
	            
	            String sql="select *from users where username=?";
	            ps= conn.prepareStatement(sql);
	            ps.setObject(1,username);
	            rs=ps.executeQuery();
	            while(rs.next()){
    
    
	            	Users users=new Users();
	            	users.setId(rs.getInt("id"));
	            	users.setUsername(rs.getString("username"));
	            	users.setPassword(rs.getString("password"));
	            	pwd=users.getPassword();
	            	username=users.getUsername();
	            }
	        } catch (SQLException e) {
    
    
	            e.printStackTrace();
	        } catch (PropertyVetoException e) {
    
    
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally {
    
    
	            try {
    
    
	            	if(rs!=null){
    
    
	            		rs.close();
	            	}
	            } catch (SQLException e) {
    
    
	                e.printStackTrace();
	            }
	            try {
    
    
	            	if(ps!=null){
    
    
	            		ps.close();
	            	}
	            } catch (SQLException e) {
    
    
	                e.printStackTrace();
	            }
	            try {
    
    
	            	if(conn!=null){
    
    
	            		conn.close();
	            	}
	            } catch (SQLException e) {
    
    
	                e.printStackTrace();
	            }
	        }
		
		SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(username,pwd,getName());
		
		
		
		return info;
	}

	
}

main

package cn.wit.shiro;

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.config.IniSecurityManagerFactory;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.apache.shiro.mgt.SecurityManager;

/**
 * 完成用户认证功能
 * @author Administrator
 *
 */
public class Authentication {
    
    
	public static void main(String[] args) {
    
    
		//拿到SecurityManager并将它放到环境当中
		Factory<SecurityManager>factory=new IniSecurityManagerFactory("classpath:shiro.ini");
		SecurityManager securityManager = factory.getInstance();
		SecurityUtils.setSecurityManager(securityManager);
		
		//拿到subject接口
		Subject subject = SecurityUtils.getSubject();
		UsernamePasswordToken taken=new UsernamePasswordToken("zhangsan","123");
		try {
    
    
			if(taken!=null){
    
    
				subject.login(taken);
			}
			if(subject.isAuthenticated()){
    
    
				System.out.println("登录成功");
			}
		} catch (UnknownAccountException e) {
    
    
			e.printStackTrace();
			System.out.println("账号或密码错误");
		}catch (IncorrectCredentialsException e) {
    
    
			e.printStackTrace();
			System.out.println("账号或密码错误");
		}
		
		
	}
}

跟踪源码

从login进入跟到SecurityManager,到它的实现类defaultSecurityManager,调用authenticator的authenticate方法,进入authenticator,它的实现类ModularRealmAuthenticator
在这里插入图片描述
里边有setRealms方法,进入Realm接口,在这里插入图片描述
Realm类层次如下,里面已经实现了多种realm了,比如之前的jdbcRealm就是这里边已经定义好的,如果要自定义realm,需要继承AuthorizingRealm,并且自定义授权同样是继承的这个类
在这里插入图片描述

AuthorizingRealm(abstract)是AuthenticatingRealm的子类
AuthenticatingRealm(abstract)中有doGetAuthenticationInfo方法,可以自定义认证
AuthorizingRealm中有doGetAuthorizationInfo方法,可以自定义授权

继承AuthenticatingRealm方法,AuthorizingRealm没有重写doGetAuthenticationInfo,所以继承类就必须重写这两个方法
在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/WA_MC/article/details/113554620