shiro安全框架 登录验证(MD5加密)

单数据源的情况

shiro.ini

[main]
#实例化数据源
dataSource=com.alibaba.druid.pool.DruidDataSource
#设置数据源的连接参数
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql://localhost:3306/shiro?useSSL=false&useUnicode=true&characterEncoding=UTF-8
dataSource.username=root
dataSource.password=123456
#采用shiro提供的jdbc访问类(JdbcRealm)操作数据库查询
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.dataSource=$dataSource
securityManager.realms=$jdbcRealm

多数据源的情况
shiro.ini

[main]
#第一个数据源的设置
#实例化数据源
dataSource1=com.alibaba.druid.pool.DruidDataSource
#设置数据源的连接参数
dataSource1.driverClassName=com.mysql.jdbc.Driver
dataSource1.url=jdbc:mysql://localhost:3306/shiro?useSSL=false&useUnicode=true&characterEncoding=UTF-8
dataSource1.username=root
dataSource1.password=123456
#采用shiro提供的jdbc访问类(JdbcRealm)操作数据库查询
jdbcRealm1=org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm1.dataSource=$dataSource1


#第二个数据源的设置
dataSource2=com.alibaba.druid.pool.DruidDataSource
#设置数据源的连接参数
dataSource2.driverClassName=com.mysql.jdbc.Driver
dataSource2.url=jdbc:mysql://localhost:3306/shiro_test?useSSL=false&useUnicode=true&characterEncoding=UTF-8
dataSource2.username=root
dataSource2.password=123456
#采用shiro提供的jdbc访问类操作数据库查询
jdbcRealm2=org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm2.dataSource=$dataSource2

#加入jdbcRealm
securityManager.realms=$jdbcRealm1,$jdbcRealm2
#设置认证策略
#认证策略:所有的数据源要全部认证成功才算成功
anthenticate=org.apache.shiro.authc.pam.AllSuccessfulStrategy
#设置指定的认证策略
securityManager.authenticator.authenticationStrategy=$anthenticate

测试代码

package com.shiro;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;

public class Demo {
    public static void main(String[] args) {
//        加载shiro.ini配置文件
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//        创建SecurityManager对象
        SecurityManager instance = factory.getInstance();
//        将SecurityManager设置到当前开发环境中来
        SecurityUtils.setSecurityManager(instance);
//        获取代表当前用户数据库数据的subject对象
        Subject subject = SecurityUtils.getSubject();
//        把需要登录的数据封装成token凭证(令牌)
        UsernamePasswordToken token = new UsernamePasswordToken("zyy", "123456");
//        通过subject的login方法验证token是否和数据库里面的数据一致
        try{
            subject.login(token);
            if (subject.isAuthenticated()){
                System.out.println("登陆成功");
            }
        }catch (Exception e){
            e = new Exception("账户名或者密码错误");
            e.printStackTrace();
        }

    }
}

查看org.apache.shiro.realm.jdbc.JdbcRealm源码

protected static final String DEFAULT_AUTHENTICATION_QUERY = "select password from users where username = ?";
    protected static final String DEFAULT_SALTED_AUTHENTICATION_QUERY = "select password, password_salt from users where username = ?";
    protected static final String DEFAULT_USER_ROLES_QUERY = "select role_name from user_roles where username = ?";
    protected static final String DEFAULT_PERMISSIONS_QUERY = "select permission from roles_permissions where role_name = ?";

可以看出 数据库的表名和字段名有要求 表名要是users 两个字段分别是username和password

这个是可以改变的 只需要我们不使用官方的JdbcRealm 所以我们自定义一个自己的JdbcRealm

注意 自己的JdbcRealm要继承和官方一样的AuthorizingRealm类
MyRealm

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

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


public class MyRealm extends AuthorizingRealm {

//    注意这里一定要声明dataSource 为了在配置文件中注入 同时要加上set方法
    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    //    用来给用户授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

//    用来认证用户信息(登录)
//    subject.login(token)传入的参数会被AuthenticationToken接收
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String name = (String) authenticationToken.getPrincipal();
        Connection con = null;
        try {
            con = dataSource.getConnection();
            PreparedStatement pstmt = con.prepareStatement("select `name`,password from users where `name`=?");
            pstmt.setString(1,name);
            ResultSet re = pstmt.executeQuery();
            while(re.next()){
                String userName = re.getString("name");
                String password = re.getString("password");
                SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userName, password, "");
                return info;
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return null;
    }
}

shiro.ini

[main]
#第一个数据源的设置
#实例化数据源
dataSource1=com.alibaba.druid.pool.DruidDataSource
#设置数据源的连接参数
dataSource1.driverClassName=com.mysql.jdbc.Driver
dataSource1.url=jdbc:mysql://localhost:3306/shiro_test?useSSL=false&useUnicode=true&characterEncoding=UTF-8
dataSource1.username=root
dataSource1.password=123456
#采用自定义的操作数据库查询
jdbcRealm1=com.realm.MyRealm
jdbcRealm1.dataSource=$dataSource1


#加入jdbcRealm
securityManager.realms=$jdbcRealm1

使用MD5加密算法
shiro.ini

[main]
#第一个数据源的设置
#实例化数据源
dataSource1=com.alibaba.druid.pool.DruidDataSource
#设置数据源的连接参数
dataSource1.driverClassName=com.mysql.jdbc.Driver
dataSource1.url=jdbc:mysql://localhost:3306/shiro_test?useSSL=false&useUnicode=true&characterEncoding=UTF-8
dataSource1.username=root
dataSource1.password=123456

#配置加密对象
hcm=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#给hcm对象设置加密的方式MD5
hcm.hashAlgorithmName=Md5
#加盐的迭代加密次数
hcm.hashIterations=3


#采用自定义的操作数据库查询
jdbcRealm1=com.realm.MyRealm
jdbcRealm1.dataSource=$dataSource1

#给自定义的Realm关联加密对象
jdbcRealm1.credentialsMatcher=$hcm

#加入jdbcRealm
securityManager.realms=$jdbcRealm1

MyRealm

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

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


public class MyRealm extends AuthorizingRealm {
//    注意这里一定要声明dataSource 为了在配置文件中注入 同时要加上set方法
    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    //    用来给用户授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

//    用来认证用户信息(登录)
//    subject.login(token)传入的参数会被AuthenticationToken接收
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String name = (String) authenticationToken.getPrincipal();
        Connection con = null;
        try {
            con = dataSource.getConnection();
            PreparedStatement pstmt = con.prepareStatement("select `name`,password from users where `name`=?");
            pstmt.setString(1,name);
            ResultSet re = pstmt.executeQuery();
            while(re.next()){
                String userName = re.getString("name");
                String password = re.getString("password");
//                这里要设置加密的盐
                SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userName, password, ByteSource.Util.bytes("006876"),"");
                return info;
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return null;
    }
}

加密
Md5Test

import org.apache.shiro.crypto.hash.Md5Hash;

public class Md5Test {
    public static void main(String[] args) {
        Md5Hash md5Hash = new Md5Hash("123456", "006876", 3);
        System.out.println(md5Hash);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值