日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java ee jaas_Java Web系列:JAAS认证和授权基础

發布時間:2023/12/10 java 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java ee jaas_Java Web系列:JAAS认证和授权基础 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.認證和授權概述

(1)認證:對用戶的身份進行驗證。

.NET基于的RBS(參考1)的認證和授權相關的核心是2個接口System.Security.Principal.IPrincipal和System.Security.Principal.IIdentity。我們自己實現認證過程,通過Thread.CurrentPrincipal來設置和讀取認證結果。認證成功后設置認證狀態和標識。

Java內置了的JAAS(參考2),核心是javax.security.auth.Subject類和javax.security.Principal接口。java對認證過程也提供了2個類型,javax.security.auth.login.LoginContext類和javax.security.auth.spi.LoginModule接口。我們自己實現認證過程,但只要實現了LoginModule就可以通過LoginContext使用一致的語法。

(2)授權:對用戶的權限進行驗證,通常使用Role(角色)管理權限。

.NET的支持基于角色的授權。.NET的IPrincipal接口的IsInRole方法是授權的核心。有兩種方式使用:1.使用內置的IPrincipal對象(如GenericIdentity),在認證的同時加載用戶的角色roles。2.自定義IPrincipal實現,實現自己的IsInRole邏輯。ASP.NET中實現的的RolePrincipal就通過將邏輯轉發給System.Web.Security.Roles靜態類。Roles依賴System.Web.Security.RoleProvider接口實現角色的查詢,我們可以通過web.config的相關節點來配置自定義的RoleProvider。

JAAS的IPrincipal接口沒有提供IsInRole方法,我們有2個選擇,要么通過多個IPrincipal表示角色,要么自定義實現IPrincipal添加角色支持。Tomcat容器實現的org.apache.catalina.realm.GenericPrincipal就和.NET中的System.Security.Principal.GenericIdentity十分類似的角色實現。

Java的Subject類和IPrincipal接口與.NET的IPrincipal接口和IIdentity的接口不容易對應。為了便于統一理解.NET和Java的核心類型,我們可以從成員的理解,可以認為Java的Principal類型相當于.NET中的IPrincipa和IIdentity兩個類型的作用。Subject只是作為Principal的聚合根。之前提到的Tomcat容器中的GenericPrincipal就即提供了hasRole和getName成員。Tomcat實現的HttpServletRequest對應的成員就是通過GenericPrincipal實現的。

#

成員

.NET

Java

認證類型

AuthenticationType

System.Security.Principal.IIdentity.AuthenticationType

javax.servlet.http.HttpServletRequest.getAuthType()

標識名稱

Name

System.Security.Principal.IIdentity.Name

java.security.Principal.getName()

角色驗證

IsInRole

System.Security.Principal.IPrincipal.IsInRole

javax.servlet.http.HttpServletRequest.isUserInRole()

2..NET Web認證和授權

ASP.NET Forms認證主采用RolePrincipal主體,未認證用戶設置為GenericIdentity標識,已認證用戶設置為FormsIdentity。RolePrincipal在驗證角色時將使用Roles靜態類通過RoleProvider進行角色驗證。通過HttpContext.User可以直接調用主體。

實現一個最簡單的自定義RoleProvider只需要繼承并實現GetRolesForUser和IsUserInRole兩個方法,通??梢允褂梦性贏pplication_Start中注入的方式實現通用的RoleProvider。

ASP.NET的forms驗證通過FormsAuthentication發送和注銷用于認證的token,通過配置web.config可以讓不同的Web服務器以相同的方式對token加密和解密以適應Web服務器負載均衡。不適用cookie承載token時,可以自定義認證邏輯,比如通過url參數方式承載token配合ssl用于app客戶端驗證等。

.NET的認證和授權示意圖:

自定義RoleProvider的示例,省略了不需要實現的部分代碼,GetRolesForUserDelegate和IsUserInRoleDelegate在Application_Start中注入即可徹底實現RoleProvider和應用服務代碼的解耦:

public classSimpleRoleProvider : RoleProvider

{

public static FuncGetRolesForUserDelegate;

public static FuncIsUserInRoleDelegate;

public override string[] GetRolesForUser(stringusername)

{

returnGetRolesForUserDelegate(username);

}

public override bool IsUserInRole(string username, stringroleName)

{

returnIsUserInRoleDelegate(username, roleName);

}

}

Forms身份驗證和RoleProvider的分別定義在web.config配置文件中。ASP.NET的配置文件示例(省略了其他配置):

.NET中還有用于配置Pricipal的兩個方法System.AppDomain.SetThreadPrincipal和System.AppDomain.SetPrincipalPolicy以及控制訪問的兩個類型System.Security.Permissions.PrincipalPermission和System.Security.Permissions.PrincipalPermissionAttribute。

3.JAAS

HttpServletRequest接口定義了6個驗證和授權相關的方法getAuthType()、login()、logout()、getRemoteUser()、isUserInRole()、getUserPrincipal()。類似ASP.NET,Forms身份驗證也在配置文件中進行配置。但由于Java熱衷于定義一堆接口將實現推遲到容器級別,LoginContext依賴的具體的LoginModule的配置也必須在容器中進行配置。因此除了web.xml,還需要配置在容器中配置JAAS的配置文件。JAAS的示意圖:

(1)JAAS 內置的登錄模塊使用:NTLoginModule:

配置:

first{

com.sun.security.auth.module.NTLoginModule Required debug=true;

};

代碼

packagecom.test.jaas1;importjava.security.Principal;importjavax.security.auth.login.LoginContext;importjavax.security.auth.login.LoginException;public classApp {public static voidmain(String[] args) {

System.setProperty("java.security.auth.login.config",

Thread.currentThread().getContextClassLoader().getResource("jaas.config").getPath());try{

LoginContext lc= new LoginContext("first");

lc.login();

System.out.println(lc.getSubject().getPrincipals().size());for(Principal item : lc.getSubject().getPrincipals()) {

System.out.println(String.format("%s principal:%s", item.getClass().getTypeName(), item.getName()));

}

lc.logout();

System.out.println(lc.getSubject().getPrincipals().size());

}catch(LoginException e) {

e.printStackTrace();

}

}

}

(2)JAAS Tomcat容器下的登錄模塊使用(參考3):

用于配置Forms認證:web.xml

Archetype Created Web Application

Admin

/admin/*

admin

admin

FORM

/login.html

/error.html

View Code

用于JAAS的LoginModule的配置:/main/java/resources/jaas.config

MyLogin{

MyLoginModule Required debug=true;

};

View Code

用于Tomcat的配置:/main/webapp/META-INF/context.xml配置(這個依賴至少還在項目內,不需要修改tomcat):

View Code

用于Tomcat的UserClass和RoleClass代碼:

importjava.security.Principal;public class UserPrincipal implementsPrincipal {privateString _name;publicUserPrincipal(String name) {this._name =name;

}

@OverridepublicString getName() {return this._name;

}

}

View Code

RoleClass:

importjava.security.Principal;public class RolePrincipal implementsPrincipal {privateString _name;publicRolePrincipal(String name) {this._name =name;

}

@OverridepublicString getName() {return this._name;

}

}

View Code

用于JAAS配置文件初始化的代碼(為了依賴tomcat的配置,在Filter中設置配置文件):

importjava.io.IOException;importjavax.servlet.Filter;importjavax.servlet.FilterChain;importjavax.servlet.FilterConfig;importjavax.servlet.ServletException;importjavax.servlet.ServletRequest;importjavax.servlet.ServletResponse;importjavax.servlet.annotation.WebFilter;importjavax.servlet.http.HttpServletRequest;

@WebFilter("/*")public class MyFilter implementsFilter {

@Overridepublic void init(FilterConfig filterConfig) throwsServletException {//TODO 自動生成的方法存根

System.setProperty("java.security.auth.login.config",

Thread.currentThread().getContextClassLoader().getResource("jaas.config").getPath());

}

@Overridepublic voiddoFilter(ServletRequest request, ServletResponse response, FilterChain chain)throwsIOException, ServletException {

chain.doFilter(newMyRequest((HttpServletRequest) request), response);

}

@Overridepublic voiddestroy() {//TODO 自動生成的方法存根

}

}

View Code

用于登錄的login.html:

Insert title here
UserName
Password

View Code

MyLoginModule實現:其中的三個name屬性必須是固定值:j_security_check、j_username和j_password。

importjava.io.IOException;importjava.util.Map;importjavax.security.auth.Subject;importjavax.security.auth.callback.Callback;importjavax.security.auth.callback.CallbackHandler;importjavax.security.auth.callback.NameCallback;importjavax.security.auth.callback.PasswordCallback;importjavax.security.auth.callback.UnsupportedCallbackException;importjavax.security.auth.login.LoginException;importjavax.security.auth.spi.LoginModule;public class MyLoginModule implementsLoginModule {privateCallbackHandler handler;privateSubject subject;

@Overridepublic void initialize(Subject subject, CallbackHandler callbackHandler, MapsharedState,

Mapoptions) {

handler=callbackHandler;this.subject =subject;

}

@Overridepublic boolean login() throwsLoginException {

Callback[] callbacks= new Callback[2];

callbacks[0] = new NameCallback("login");

callbacks[1] = new PasswordCallback("password", true);try{

handler.handle(callbacks);

String name= ((NameCallback) callbacks[0]).getName();

String password= String.valueOf(((PasswordCallback) callbacks[1]).getPassword());if (name != null && name.equals("user123") && password != null && password.equals("pass123")) {return true;

}//If credentials are NOT OK we throw a LoginException

throw new LoginException("Authentication failed");

}catch(IOException e) {throw newLoginException(e.getMessage());

}catch(UnsupportedCallbackException e) {throw newLoginException(e.getMessage());

}

}

@Overridepublic boolean commit() throwsLoginException {

subject.getPrincipals().add(new UserPrincipal("user123"));

subject.getPrincipals().add(new RolePrincipal("admin"));return true;

}

@Overridepublic boolean abort() throwsLoginException {//TODO 自動生成的方法存根

return false;

}

@Overridepublic boolean logout() throwsLoginException {

subject.getPrincipals().clear();return true;

}

}

View Code

在.NET的RBS基礎上實現RBAC(參考4)是可行的,但JAAS....。JAAS只要用過的人都對其印象深刻。

4.參考

(1)https://msdn.microsoft.com/en-us/library/52kd59t0(v=vs.90).aspx

(2)http://docs.oracle.com/javase/8/docs/technotes/guides/security/jaas/JAASRefGuide.html

(3)http://www.byteslounge.com/tutorials/jaas-form-based-authentication-in-tomcat-example

(4)http://csrc.nist.gov/groups/SNS/rbac/

5.小結:

JAAS抽象的不切實際,實現又全靠容器,不同容器的實現還不一致,IPrincipal又不能直接支持Servlet認證和授權相關的方法。至少應該像.NET一樣提供數據結構級別的角色認證類型,而不是跑偏成現在這樣。容器要么自己擴展IPrincipal支持角色,要么通過配置傳入指定類型的IPrincipal子類來區分角色和用戶。只能希望Apache Shiro和Spring等第三方提供的一些實現能有更高的可用性。

總結

以上是生活随笔為你收集整理的java ee jaas_Java Web系列:JAAS认证和授权基础的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。