Spring Security框架下簡單實現遠程用戶限制IP地址內登陸

    某些場景下,但願用戶只能從限定的IP地址上登入系統,姑且勿論限定IP登陸能帶來多少安全性上的改善,咱們來試試在使用Spring Security安全框架下,如何實現。java

    有人確定會提出一個方案,你看,簡單,只要AuthenticationManager配置裏,增長一個AuthenticationProvider就能夠了,固然,這個是個很好的方案,也很容易實現,只要自定義AuthenticationProvider,在其authenticate方法裏實現邏輯就能夠了。而我在這裏要說的是一種更爲簡單的辦法,知足基本設計要求:web

  • 在本地認證庫裏同時可配置IP限定規則正則表達式

  • IP限定規則能夠簡單支持:單個IP;逗號,分號分割的多個IP;IP地址範圍(同時支持多個定義)安全

  • 驗證錯誤時拋出異常
    框架

    由於我採用的是本地庫的認證,使用的是DaoAuthenticationProvider,且自定義了UserDetailsService,能夠從UserDetailsService中讀取出用戶對應的限定IP配置,而後要作的是,咱們繼承DaoAuthenticationProvider自定義一個ExDaoAuthenticationProvider,重載其additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication)方法,進行IP範圍check,以下爲代碼片斷:
ide

//省略imports
public class ExDaoAuthenticationProvider extends DaoAuthenticationProvider {
    // 框架MessageSource
    private MessageSourceAccessor exmessage = ExtrasMessageSource.getAccessor();

    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails,
            UsernamePasswordAuthenticationToken authentication)
            throws AuthenticationException {
        //執行父類裏的檢查
        super.additionalAuthenticationChecks(userDetails, authentication);
        //web,取得遠程ip
        String remoteAddress = null;
        Object details = authentication.getDetails();
        if (details instanceof WebAuthenticationDetails) {
             WebAuthenticationDetails webDetails = (WebAuthenticationDetails) details;
             remoteAddress = webDetails.getRemoteAddress();
        }
        // 例行null檢查遠程ip,若空,能夠直接返回或異常
        if (remoteAddress == null || remoteAddress.trim().length() == 0) {
                throw new BadCredentialsException(
                        exmessage
                                .getMessage("framework.security.notAuthorizedIp"));
        }
        String validAddress = null;
        // ... ... 取得限定IP設定,能夠從UserDetails裏讀取或其餘方法,省略......
        {validAddress = ... ...}
        //若是未限定ip,返回
        if (validAddress == null || validAddress.trim().length() == 0) {
            return;
        }
        
        //檢查ip有效性
        if (!validateRemoteAddress(validAddress, remoteAddress)) {
            throw new BadCredentialsException(
                    exmessage.getMessage("framework.security.notAuthorizedIp"));
        }

    }

    private boolean validateRemoteAddress(String validAddress,
            String remoteAddress) {
        // 逗號,分號分割多個ip
        String[] address = validAddress.split(",|;");
        if (address != null && address.length > 0) {
            for (String addr : address) {
                if (match(addr, remoteAddress))
                    return true;
            }
        }
        return false;
    }

    private boolean match(String addr, String remoteAddress) {
        // 用各類正則表達式等驗證IP有效性,省略... ...
        if (remoteAddress.matches(addr)) {
            return true;
        }
        ... ...
        // 圍在有效IP裏,則false
        return false;
    }
}

    最後,ExDaoAuthenticationProvider替換原配置,運行web應用,就能夠完成對遠程用戶登陸IP的限制了,非受權IP處登陸,系統會拋出異常,界面顯示給用戶錯誤信息。設計

    經過上述辦法,能夠快速簡單的實現基於本地認證庫的IP限定邏輯,你們如有更好的實現方法,歡迎分享... ...code

相關文章
相關標籤/搜索