【发布时间】:2013-04-11 11:19:41
【问题描述】:
环境:
- JAVA
- 玻璃鱼
- 不同机器上的 REST 服务
- HTML5 客户端 AJAX 和 JQuery
- 球衣
这是我目前实现的:
HTML5-客户端
$('#btnSignIn').click(function () {
var username = $("#username").val();
var password = $("#password").val();
function make_base_auth(user, password) {
var tok = user + ':' + password;
var final = "Basic " + $.base64.encode(tok);
console.log("FINAL---->" + final);
alert("FINAL---->" + final);
return final;
}
$.ajax({
type: "GET",
contentType: "application/json",
url: "http://localhost:8080/SesameService/webresources/users/secured/login",
crossDomain: true,
dataType: "text",
async: false,
data: {},
beforeSend: function (xhr) {
xhr.setRequestHeader('authorization', make_base_auth(username, password));
},
success: function () {
alert('Thanks for your signin in! ');
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(textStatus, errorThrown);
alert(' Error in signIn-process!! ' + textStatus);
}
});
});
服务器
在安全中,我没有启用安全管理器,它被禁用了!
我已经为 Glassfish 配置了 BASIC-authentication,我的 web.xml 看起来像这样:
<servlet-mapping>
<servlet-name>ServletAdaptor</servlet-name>
<url-pattern>/webresources/*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>REST Protected resources</web-resource-name>
<description/>
<url-pattern>/users/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
<role-name>customer</role-name>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>jdbcRealm</realm-name>
</login-config>
<security-role>
<role-name>admin</role-name>
</security-role>
<security-role>
<role-name>user</role-name>
</security-role>
<security-role>
<description/>
<role-name>customer</role-name>
</security-role>
玻璃鱼
日志
FINE: [Web-Security] Setting Policy Context ID: old = null ctxID = SesameService/SesameService
FINE: [Web-Security] hasUserDataPermission perm: ("javax.security.jacc.WebUserDataPermission" "/webresources/users/secured/login" "GET")
FINE: [Web-Security] hasUserDataPermission isGranted: true
FINE: [Web-Security] Policy Context ID was: SesameService/SesameService
FINE: [Web-Security] hasResource isGranted: true
FINE: [Web-Security] hasResource perm: ("javax.security.jacc.WebResourcePermission" "/webresources/users/secured/login" "GET")
问题:
-
如果我在用户注册时在客户端加密(不编码)密码并在 SSL/HTTPS 下传输它,这是实现此安全且良好的方法吗?
-
如果我在没有客户端的情况下使用 REST 服务,它总是打开的,为什么?没有基本身份验证?我理解这些 url 模式有什么问题吗?
http://localhost:8080/SesameService/webresources/users/secured/login -
如果我得到这个工作如何测试它,因为现在如果我验证一次,我总是被授权?是否可以在 REST 服务中以编程方式“注销”或一般如何实现注销?
-
当在带有强制性 base64 编码的用户名:密码的标头中使用授权时,我是否还必须将我的用户名和密码编码到 DB 中?我试过了,并将编码(允许的值是 Hex 和 Base64)添加到 jdbcRealm 到 Glassfish,似乎密码就足够了,但是当两者都在客户端编码时会发生什么?
更新:我更改了 web.xml,现在在浏览器中直接调用 REST 服务时,BASIC-authentication 正在工作:http://localhost:8080/SesameService/users/secured/login
变化:
- 我在 Glassfish 中启用了安全管理器
- 我更改了 url 模式
<servlet-mapping>
<servlet-name>ServletAdaptor</servlet-name>
<url-pattern>/*</url-pattern>----> I took webresources off. It was generated by Netbeans
</servlet-mapping>
- 我将服务的 url 更改为:
http://localhost:8080/SesameService/users/secured/login
现在我在尝试从 HTML5 客户端进行身份验证时收到 HTTP/1.1 401 Unauthorized。
请求标头:
Origin: http://localhost:8383
Host:localhost:8080
Connection:keep-alive
Access-Control-Request-Method:GET
Access-Control-Request-Headers:authorization,content-type
回应:
x-powered-by:Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 3.1.2.2 Java/Oracle Corporation/1.7)
WWW-Authenticate:Basic realm="jdbcRealm"
Server:GlassFish Server Open Source Edition 3.1.2.2
Pragma:No-cache
Expires:Thu, 01 Jan 1970 02:00:00 EET
Date:Sat, 13 Apr 2013 15:25:06 GMT
Content-Type:text/html
Content-Length:1073
Cache-Control:no-cache
更新 2
当我尝试使用 JavaScript + Authorization-header 进行身份验证时,出现 401 错误,并且在日志中:
FINE: [Web-Security] Setting Policy Context ID: old = null ctxID = SesameService/SesameService
FINE: [Web-Security] hasUserDataPermission perm: ("javax.security.jacc.WebUserDataPermission" "/users/secured/login" "OPTIONS")
FINE: [Web-Security] hasUserDataPermission isGranted: true---->!!!!!!!!!!!!!
FINE: [Web-Security] Policy Context ID was: SesameService/SesameService
FINE: [Web-Security] Codesource with Web URL: file:/SesameService/SesameService
FINE: [Web-Security] Checking Web Permission with Principals : null------->!!!!!!!
FINE: [Web-Security] Web Permission = ("javax.security.jacc.WebResourcePermission" "/users/secured/login" "OPTIONS")
FINEST: JACC Policy Provider: PolicyWrapper.implies, context (SesameService/SesameService)- result was(false) permission (("javax.security.jacc.WebResourcePermission" "/users/secured/login" "OPTIONS"))
FINE: [Web-Security] hasResource isGranted: false------->!!!!!!!!!
FINE: [Web-Security] hasResource perm: ("javax.security.jacc.WebResourcePermission" "/users/secured/login" "OPTIONS")
FINEST: JACC Policy Provider: PolicyWrapper.getPermissions(cs), context (null) codesource ((null <no signer certificates>)) permissions: java.security.Permissions@5d4de3b0 (
更新 3 我不能成为第一个也是唯一一个尝试在跨域案例中使用 BASIC 进行身份验证的人。 我像这样更改了我的跨源过滤器:
response.getHttpHeaders().putSingle("Access-Control-Allow-Headers", "Authorization");
不再出现 401 错误,但 JavaScript 中仍然存在错误。在 Glassfish 日志中:
FINEST: JACC Policy Provider:
getPolicy (SesameService/SesameService) is NOT in service----->!!!!!!!!
FINE: JACC Policy Provider: file arrival check type: granted arrived: false exists: false lastModified: 0 storedTime: 1365968416000 state: deleted SesameService/SesameService
FINE: JACC Policy Provider: file arrival check type: excluded arrived: false exists: false lastModified: 0 storedTime: 0 state: deleted SesameService/SesameService
FINE: TM: getTransaction: tx=null, tm=null
FINE: TM: componentDestroyedorg.apache.catalina.servlets.DefaultServlet@227fe9a8
FINE: TM: resourceTable before: 0
FINE: TM: resourceTable after: 0
顺便说一句,因为我从来没有做过这项工作,所以这项工作的工作方式与在自己的域中直接调用 REST 服务相同。那么,首先打开客户端请求、服务器请求和用户名密码窗口,然后客户端请求和服务器验证并响应页面?我正在尝试获取它:其中包含授权标头的请求,来自服务器的响应以及来自其余服务的结果,仅此而已。知道如何保护 REST 服务吗?比那更容易?这是不可能的。
更新 4
我只是试图将我的 HTML5 客户端移动到 java web-project 下,只是纯 html 页面和同一域下,BASIC 身份验证工作 100%。所以原因是因为跨域环境。
【问题讨论】:
-
您是否尝试过关闭并重新打开浏览器?使用 BASIC auth,浏览器会缓存凭据,直到您关闭它 - 它不会不断地反复提示您。不 - 没有办法使用 BASIC 注销,因为凭据是随每个请求一起发送的。
-
我在 Chrome 和 Firefox 中使用 Private/ignognito-winwows。在任何情况下我什至看不到基本登录窗口,我每次都能进入。我认为问题出在 url-patterns 中,但我不知道为什么以及如何。
-
我启用了安全管理器,现在它似乎真的在使用它,但是我仍然在没有基本身份验证的情况下进入。:FINEST: JDBCRealm : jaas-context= jdbcRealm, datasource-jndi = sesame , db-user = null, digest-algorithm = none, encoding = null, charset = null INFO: SEC1115: Realm [jdbcRealm] of classtype [com.sun.enterprise.security.auth.realm.jdbc.JDBCRealm] 成功创建。 FINE:已配置领域:jdbcRealm FINE:默认领域设置为:jdbcRealm 信息:SEC1011:安全服务已成功启动 FINE:已安装策略。不会重新安装。
-
把你的更新放在你的问题的顶部会让你很难(不可能?)理解发生了什么。我什至不知道你最初的问题是从哪里开始的。
标签: java html http-headers authorization basic-authentication