2016-10-30 3 views
0

저는 엔터프라이즈 웹 앱의 보안을 유지하려고합니다! 나는 자원을 제약해야한다.사용자 정의 JDBCrealm을 만드는 방법은 무엇입니까?

나는 db (사용자 및 역할)에 모두 저장 했으므로 fileRealm을 만들거나 (Glassfish) 서버에 사용자의 자격 증명을 저장하지 않습니다. 또한, jBCrypt를 사용하여 사용자의 암호를 암호화하므로 표준 jdbcRealm을 사용할 수 없습니다.

내 자원을 안전하게 보호하려면 어떻게해야합니까?

사용자 정의 jdbcRealm에 대해 생각하고 있습니다. 올바른 방법일까요? 어떻게 그것을 만들고 사용할 수 있습니까?

일부 기존 프레임 워크가 도움이 될 수 있습니까?

미리 감사드립니다.

답변

1

프레임 워크 Apache Shiro을 사용하는 것이 좋습니다. 구성 파일은

[main] 

sha256Matcher = org.apache.shiro.authc.credential.HashedCredentialsMatcher 
sha256Matcher.hashAlgorithmName = SHA-256 
sha256Matcher.hashIterations=1 
# base64 encoding 
sha256Matcher.storedCredentialsHexEncoded = false 

#datasource type 
ds = org.apache.shiro.jndi.JndiObjectFactory 

#datasourcename 
ds.resourceName = cfresource 

#datasourcetype 
ds.requiredType = javax.sql.DataSource 




#configuring jdbc realm 
jdbcRealm = com.connectifier.authc.realm.CustomJDBCRealm 
jdbcRealm.credentialsMatcher = $sha256Matcher 
jdbcRealm.dataSource=$ds 
jdbcRealm.userRolesQuery=select name from role where email = ? and isactive=1 
jdbcRealm.authenticationQuery=select hash, salt from user where email = ? 
jdbcRealm.permissionsLookupEnabled=false 
securityManager.realms = $jdbcRealm 
#login url 
authc.loginUrl =/

#page to redirected to after logout 
logout.redirectUrl =/

#page to where to land after login 
authc.successUrl =/

#username parameter name in the loginform 
authc.usernameParam = username 

#password parameter name in the loginform 
authc.passwordParam = password 

#rememberme parameter name in the loginform 
authc.rememberMeParam=rememberme 

#cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager 
#securityManager.cacheManager = $cacheManager 
#jdbcRealm.authenticationCachingEnabled = true 

[urls] 
# The /login.jsp is not restricted to authenticated users (otherwise no one could log in!), but 
# the 'authc' filter must still be specified for it so it can process that url's 
# login submissions. It is 'smart' enough to allow those requests through as specified by the 
# shiro.loginUrl above. 

/* = anon 

CustomJDBCRealm 최우선 JDBCRealm

package com.connectifier.authc.realm; 

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

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.codec.Base64; 
import org.apache.shiro.realm.jdbc.JdbcRealm; 
import org.apache.shiro.util.ByteSource; 
import org.apache.shiro.util.JdbcUtils; 
import org.apache.shiro.util.SimpleByteSource; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

/** 
* @author kiranchowdhary 
* 
*   Application specific JDBC realm. If required override methods of {@link JdbcRealm} to load users, roles and 
*   permissions from database. 
* 
*   Do not override configuration in code if it can be done via shiro.ini file. 
*/ 
public class CustomJDBCRealm extends JdbcRealm { 

    private static final Logger log = LoggerFactory.getLogger(JdbcRealm.class); 

    public CustomJDBCRealm() { 
     super(); 
     setSaltStyle(SaltStyle.COLUMN); 
    } 

    /** 
    * overriding the method which is in JdbcRealm. If SaltStyle is COLUMN, then gets String salt value from database 
    * and forms salt byte array of type {@link ByteSource} with decoded string salt value and sets it to salt value of 
    * AuthenticationInfo. 
    */ 
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { 

     UsernamePasswordToken upToken = (UsernamePasswordToken) token; 
     String username = upToken.getUsername(); 

     // Null username is invalid 
     if (username == null) { 
      throw new AccountException("Null usernames are not allowed by this realm."); 
     } 

     Connection conn = null; 
     SimpleAuthenticationInfo info = null; 
     try { 
      conn = dataSource.getConnection(); 

      String password = null; 
      String salt = null; 
      switch (saltStyle) { 
      case NO_SALT: 
      case CRYPT: 
      case EXTERNAL: 
       return super.doGetAuthenticationInfo(token); 
      case COLUMN: 
       String[] queryResults = getPasswordForUser(conn, username); 
       password = queryResults[0]; 
       salt = queryResults[1]; 
       break; 
      } 

      if (password == null) { 
       throw new UnknownAccountException("No account found for user [" + username + "]"); 
      } 

      info = new SimpleAuthenticationInfo(username, password.toCharArray(), getName()); 

      if (salt != null) { 
       info.setCredentialsSalt(new SimpleByteSource(Base64.decode(salt))); 
      } 

     } catch (SQLException e) { 
      final String message = "There was a SQL error while authenticating user [" + username + "]"; 
      if (log.isErrorEnabled()) { 
       log.error(message, e); 
      } 

      // Rethrow any SQL errors as an authentication exception 
      throw new AuthenticationException(message, e); 
     } finally { 
      JdbcUtils.closeConnection(conn); 
     } 

     return info; 
    } 

    private String[] getPasswordForUser(Connection conn, String username) throws SQLException { 

     String[] result; 
     boolean returningSeparatedSalt = false; 
     switch (saltStyle) { 
     case NO_SALT: 
     case CRYPT: 
     case EXTERNAL: 
      result = new String[1]; 
      break; 
     default: 
      result = new String[2]; 
      returningSeparatedSalt = true; 
     } 

     PreparedStatement ps = null; 
     ResultSet rs = null; 
     try { 
      ps = conn.prepareStatement(authenticationQuery); 
      ps.setString(1, username); 

      // Execute query 
      rs = ps.executeQuery(); 

      // Loop over results - although we are only expecting one result, 
      // since usernames should be unique 
      boolean foundResult = false; 
      while (rs.next()) { 

       // Check to ensure only one row is processed 
       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); 
       } 

       foundResult = true; 
      } 
     } finally { 
      JdbcUtils.closeResultSet(rs); 
      JdbcUtils.closeStatement(ps); 
     } 

     return result; 
    } 
} 
+0

들으 많은 이하 아래, 난 지금 내가 0 표와 너무 많은 질문이 ... 내가 질문을 게시 한 후 시로를 사용하기 시작입니다 나는 다른 사람들을 게시 할 수 없다 : ( – Marco

관련 문제