zoukankan      html  css  js  c++  java
  • shiro 通过jdbc连接数据库

    本文介绍shiro通过jdbc连接数据库,连接池采用阿里巴巴的druid的连接池

    参考文档:https://www.w3cschool.cn/shiro/xgj31if4.html

         https://www.w3cschool.cn/shiro/h5it1if8.html

    pom.xml的配置

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
            <artifactId>shiro-example-chapter2</artifactId>
            <groupId>com.github.zhangkaitao</groupId>
            <version>SNAPSHOT</version>
        <modelVersion>4.0.0</modelVersion>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.7</source>
                        <target>1.7</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
        <dependencies>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.16</version>
            </dependency>
    
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>1.7.25</version>
                <scope>test</scope>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.1.3</version>
            </dependency>
    
    
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.9</version>
                <scope>test</scope>
            </dependency>
    
    
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-core</artifactId>
                <version>1.2.2</version>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.25</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.8</version>
            </dependency>
    
        </dependencies>
    
    
    </project>

    shiro.ini 文件的配置

    [main]
    dataSource=com.alibaba.druid.pool.DruidDataSource
    dataSource.driverClassName=com.mysql.jdbc.Driver
    dataSource.url=jdbc:mysql://localhost:3306/shiro
    dataSource.username=root
    dataSource.password=123456
    jdbcRealm.dataSource=$dataSource


    jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm

    securityManager.realms=$jdbcRealm
    jdbcRealm  shiro框架已经集成的安全域,安全域的作用是将资源(数据库,缓存,磁盘文件等)中用户身份的集合和需要匹配的集合进行验证,决定登录用户的身份是否能验证成功的功能。如果要自定义安全域,只要继承
    AuthorizingRealm 这个接口。实现doGetAuthenticationInfo() 身份验证这个方法即可。

    测试类的方法
    public class TestJdbcLogin{ 
    @Test
    public void testJDBCRealm() { //1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-jdbc-realm.ini"); //2、得到SecurityManager实例 并绑定给SecurityUtils org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); //3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证) Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123"); try { //4、登录,即身份验证 subject.login(token); } catch (IncorrectCredentialsException e) { //5、身份验证失败 e.printStackTrace(); System.out.println("密码错误"); }catch (DisabledAccountException e){ System.out.println("禁用的账户"); } Assert.assertEquals(true, subject.isAuthenticated()); //断言用户已经登录 //6、退出 subject.logout(); }
    }

    JdbcRealm 类

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    package org.apache.shiro.realm.jdbc;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Collection;
    import java.util.Iterator;
    import java.util.LinkedHashSet;
    import java.util.Set;
    import javax.sql.DataSource;
    import org.apache.shiro.authc.AccountException;
    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.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.authz.AuthorizationException;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.config.ConfigurationException;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.apache.shiro.util.JdbcUtils;
    import org.apache.shiro.util.ByteSource.Util;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class JdbcRealm extends AuthorizingRealm {
        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 = ?";
        private static final Logger log = LoggerFactory.getLogger(JdbcRealm.class);
        protected DataSource dataSource;
        protected String authenticationQuery = "select password from users where username = ?";
        protected String userRolesQuery = "select role_name from user_roles where username = ?";
        protected String permissionsQuery = "select permission from roles_permissions where role_name = ?";
        protected boolean permissionsLookupEnabled = false;
        protected JdbcRealm.SaltStyle saltStyle;
    
        public JdbcRealm() {
            this.saltStyle = JdbcRealm.SaltStyle.NO_SALT;
        }
    
        public void setDataSource(DataSource dataSource) {
            this.dataSource = dataSource;
        }
    
        public void setAuthenticationQuery(String authenticationQuery) {
            this.authenticationQuery = authenticationQuery;
        }
    
        public void setUserRolesQuery(String userRolesQuery) {
            this.userRolesQuery = userRolesQuery;
        }
    
        public void setPermissionsQuery(String permissionsQuery) {
            this.permissionsQuery = permissionsQuery;
        }
    
        public void setPermissionsLookupEnabled(boolean permissionsLookupEnabled) {
            this.permissionsLookupEnabled = permissionsLookupEnabled;
        }
    
        public void setSaltStyle(JdbcRealm.SaltStyle saltStyle) {
            this.saltStyle = saltStyle;
            if (saltStyle == JdbcRealm.SaltStyle.COLUMN && this.authenticationQuery.equals("select password from users where username = ?")) {
                this.authenticationQuery = "select password, password_salt from users where username = ?";
            }
    
        }
    
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            UsernamePasswordToken upToken = (UsernamePasswordToken)token;
            String username = upToken.getUsername();
            if (username == null) {
                throw new AccountException("Null usernames are not allowed by this realm.");
            } else {
                Connection conn = null;
                SimpleAuthenticationInfo info = null;
    
                try {
                    String salt;
                    try {
                        conn = this.dataSource.getConnection();
                        String password = null;
                        salt = null;
                        switch(this.saltStyle) {
                        case NO_SALT:
                            password = this.getPasswordForUser(conn, username)[0];
                            break;
                        case CRYPT:
                            throw new ConfigurationException("Not implemented yet");
                        case COLUMN:
                            String[] queryResults = this.getPasswordForUser(conn, username);
                            password = queryResults[0];
                            salt = queryResults[1];
                            break;
                        case EXTERNAL:
                            password = this.getPasswordForUser(conn, username)[0];
                            salt = this.getSaltForUser(username);
                        }
    
                        if (password == null) {
                            throw new UnknownAccountException("No account found for user [" + username + "]");
                        }
    
                        info = new SimpleAuthenticationInfo(username, password.toCharArray(), this.getName());
                        if (salt != null) {
                            info.setCredentialsSalt(Util.bytes(salt));
                        }
                    } catch (SQLException var12) {
                        salt = "There was a SQL error while authenticating user [" + username + "]";
                        if (log.isErrorEnabled()) {
                            log.error(salt, var12);
                        }
    
                        throw new AuthenticationException(salt, var12);
                    }
                } finally {
                    JdbcUtils.closeConnection(conn);
                }
    
                return info;
            }
        }
    
        private String[] getPasswordForUser(Connection conn, String username) throws SQLException {
            boolean returningSeparatedSalt = false;
            String[] result;
            switch(this.saltStyle) {
            case NO_SALT:
            case CRYPT:
            case EXTERNAL:
                result = new String[1];
                break;
            case COLUMN:
            default:
                result = new String[2];
                returningSeparatedSalt = true;
            }
    
            PreparedStatement ps = null;
            ResultSet rs = null;
    
            try {
                ps = conn.prepareStatement(this.authenticationQuery);
                ps.setString(1, username);
                rs = ps.executeQuery();
    
                for(boolean foundResult = false; rs.next(); foundResult = true) {
                    if (foundResult) {
                        throw new AuthenticationException("More than one user row found for user [" + username + "]. Usernames must be unique.");
                    }
    
                    result[0] = rs.getString(1);
                    if (returningSeparatedSalt) {
                        result[1] = rs.getString(2);
                    }
                }
            } finally {
                JdbcUtils.closeResultSet(rs);
                JdbcUtils.closeStatement(ps);
            }
    
            return result;
        }
    
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            if (principals == null) {
                throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
            } else {
                String username = (String)this.getAvailablePrincipal(principals);
                Connection conn = null;
                Set<String> roleNames = null;
                Set permissions = null;
    
                try {
                    conn = this.dataSource.getConnection();
                    roleNames = this.getRoleNamesForUser(conn, username);
                    if (this.permissionsLookupEnabled) {
                        permissions = this.getPermissions(conn, username, roleNames);
                    }
                } catch (SQLException var11) {
                    String message = "There was a SQL error while authorizing user [" + username + "]";
                    if (log.isErrorEnabled()) {
                        log.error(message, var11);
                    }
    
                    throw new AuthorizationException(message, var11);
                } finally {
                    JdbcUtils.closeConnection(conn);
                }
    
                SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
                info.setStringPermissions(permissions);
                return info;
            }
        }
    
        protected Set<String> getRoleNamesForUser(Connection conn, String username) throws SQLException {
            PreparedStatement ps = null;
            ResultSet rs = null;
            LinkedHashSet roleNames = new LinkedHashSet();
    
            try {
                ps = conn.prepareStatement(this.userRolesQuery);
                ps.setString(1, username);
                rs = ps.executeQuery();
    
                while(rs.next()) {
                    String roleName = rs.getString(1);
                    if (roleName != null) {
                        roleNames.add(roleName);
                    } else if (log.isWarnEnabled()) {
                        log.warn("Null role name found while retrieving role names for user [" + username + "]");
                    }
                }
            } finally {
                JdbcUtils.closeResultSet(rs);
                JdbcUtils.closeStatement(ps);
            }
    
            return roleNames;
        }
    
        protected Set<String> getPermissions(Connection conn, String username, Collection<String> roleNames) throws SQLException {
            PreparedStatement ps = null;
            LinkedHashSet permissions = new LinkedHashSet();
    
            try {
                ps = conn.prepareStatement(this.permissionsQuery);
                Iterator i$ = roleNames.iterator();
    
                while(i$.hasNext()) {
                    String roleName = (String)i$.next();
                    ps.setString(1, roleName);
                    ResultSet rs = null;
    
                    try {
                        rs = ps.executeQuery();
    
                        while(rs.next()) {
                            String permissionString = rs.getString(1);
                            permissions.add(permissionString);
                        }
                    } finally {
                        JdbcUtils.closeResultSet(rs);
                    }
                }
            } finally {
                JdbcUtils.closeStatement(ps);
            }
    
            return permissions;
        }
    
        protected String getSaltForUser(String username) {
            return username;
        }
    
        public static enum SaltStyle {
            NO_SALT,
            CRYPT,
            COLUMN,
            EXTERNAL;
    
            private SaltStyle() {
            }
        }
    }

    标红的查询语句正是shiro框架已经集成的查询语句,所以建表的时候要根据相应的表名建表

    另外可以参考这篇文章:http://blog.51cto.com/luchunli/1828080


























  • 相关阅读:
    CSS魔法堂:选择器及其优先级
    HTML5 placeholder实际应用经验分享及拓展
    WEBAPP开发技巧(手机网站开发注意事项)
    PhotoShop的10大误区
    django之搜索引擎功能实现
    django之使用git协作开发项目
    docker简单操作
    docker之container eb7a144fe8ce is using its referenced image 9b9cb95443b5
    django之动态轮播图技术的实现
    django之Model(数据表)的增删改查
  • 原文地址:https://www.cnblogs.com/blogxiao/p/8509433.html
Copyright © 2011-2022 走看看