1. 程式人生 > >spring security與 shiro的 簡單對比

spring security與 shiro的 簡單對比

spring security 介面 RequestMatcher 用於匹配路徑,對路徑做特殊的請求,類似於shiro的

抽象類 PathMatchingFilter,但是 RequestMatcher 作用粒度更細,例如可只另某些路徑受

csrf保護,spring security也 可以自定義filter,來干擾正常的filter運作 

下面是 shiro 與 spring security 部分實現

shiro 自定義過濾器部分實現

public class SysUserFilter extends PathMatchingFilter {

    @Autowired
    private UserService userService;

    @Override
    protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {

        String username = (String) SecurityUtils.getSubject().getPrincipal();
        request.setAttribute(Constants.CURRENT_USER, userService.list("username",username).get(0));
        return true;
    }
}

 spring security 請求匹配器

public class CsrfSecurityRequestMatcher implements RequestMatcher {
    protected Log log = LogFactory.getLog(getClass());
    private Pattern allowedMethods = Pattern
            .compile("^(GET|HEAD|TRACE|OPTIONS)$");
    /**
     * 需要排除的url列表
     */
    private List<String> execludeUrls;

    @Override
    public boolean matches(HttpServletRequest request) {
        if (execludeUrls != null && execludeUrls.size() > 0) {
            String servletPath = request.getServletPath();
            for (String url : execludeUrls) {
                if (servletPath.contains(url)) {
                    log.info("++++"+servletPath);
                    return false;
                }
            }
        }

        System.out.println("*****:-:"+!allowedMethods.matcher(request.getMethod()).matches());
        return !allowedMethods.matcher(request.getMethod()).matches();
    }

    public List<String> getExecludeUrls() {
        return execludeUrls;
    }

    public void setExecludeUrls(List<String> execludeUrls) {
        this.execludeUrls = execludeUrls;
    }
}

spring security 和 shiro 對加密都提供了各種各樣的支援 例如 BCryptPasswordEncoder 採用 SHA-256 + 隨機鹽 + 祕鑰 對密碼進行加密。shrio 的 SimpleHash 提供雜湊演算法的支援,生成資料的摘要資訊.

shiro 雜湊 加密

String newPassword = new SimpleHash(
algorithmName,
user.getPassword(),
ByteSource.Util.bytes(user.getCredentialsSalt()),
hashIterations).toHex();

spring security

BCryptPasswordEncoder bpe = new BCryptPasswordEncoder();
user.setPassword(bpe.encode(user.getPassword()));

shiro 的 AuthorizingRealm 的 doGetAuthorizationInfo方法 與 doGetAuthenticationInfo 一個 是定義 獲取 使用者許可權資訊 的方法,一 個 是 定義使用者身份認證及獲取使用者身份的方法,

而 spring security 也有 資源 角色 授權器 FilterInvocationSecurityMetadataSource,定義資源url 與 角色許可權的關係 , 決策 管理器 AccessDecisionManager 定義許可權滿足的規則,

下面是 shiro realm 部分 程式碼例子

shiro 自定義 realm

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 最終判斷邏輯是 WildcardPermission implies resource [role *]

String username = (String)principals.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

RoleVo roleVo = userService.findRoles(username);
Set<String> roleNameSet = roleVo.getRoleNameSet();
Set<String> resourceNameSet = roleVo.getResourceNameSet();

System.out.println("boolean:"+ resourceNameSet.contains("user:view"));

authorizationInfo.setRoles(roleNameSet);
authorizationInfo.setStringPermissions(resourceNameSet);




return authorizationInfo;
}



/*
用於身份認證, 一般登入時就會呼叫此方法
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String)token.getPrincipal();
try {
List<User> userList = userService.list("username", username);
User user = userList.get(0);

if(user == null) {
throw new UnknownAccountException();//沒找到帳號
}

if(Boolean.TRUE.equals(false)) {
throw new LockedAccountException(); //帳號鎖定
}

//交給AuthenticatingRealm使用CredentialsMatcher進行密碼匹配,如果覺得人家的不好可以自定義實現
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
user.getUsername(), //使用者名稱
user.getPassword(), //密碼
ByteSource.Util.bytes(user.getUsername()+user.getSalt()),//salt=username+salt
getName() //realm name
);
return authenticationInfo;

} catch (Exception e) {
e.printStackTrace();
}

return null;




}

spring security 對 前端安全 有 很好的實現,

例如 防止

CSRF 跨站請求偽造,是一種挾制使用者在當前已登入的web應用上執行非本意操作的攻擊方法

XSS 跨站指令碼,是 一種 網站應用程式的安全漏洞攻擊,是程式碼注入的一種,它允許惡意使用者將程式碼注入到網頁上,其他使用者在觀看網頁時就會受到影響

歡迎加入 微服務交流群 222700500