I got a Java-Webapp running on Wildfly 8. I try to secure my restful webservice with resteasy Annotations. I use the command line tool curl to test the rest api.
The basic authentication setup seems to work. Http requests to Webservices with annotation "@PermitAll" work fine. Curl says:
~ % curl -v http://localhost:8080/ItilityServer-web/rest/account
> GET /ItilityServer-web/rest/account HTTP/1.1
> User-Agent: curl/7.40.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 200 OK
< Connection: keep-alive
< X-Powered-By: Undertow/1
< Server: WildFly/8
< Content-Length: 0
< Date: Wed, 28 Jan 2015 10:47:11 GMT
<
* Connection #0 to host localhost left intact
But http requests containing valid username and password get rejected with status code 401 not authorized. Wildfly logs the error unmatched password:
2015-01-28 11:42:43,565 TRACE [org.jboss.security] (default task-5) PBOX000263: Executing query SELECT a.password FROM Account a WHERE a.name = ? with username hans
2015-01-28 11:42:43,566 DEBUG [org.jboss.security] (default task-5) PBOX000283: Bad password for username hans
But this is not true. The decrypted authorization details "aGFuczpoZWxtaWhlbG1paGVsbWk=" are hans:helmihelmihelmi and this username and password are stored in my db. The same jpql-queries as the security-domain uses result in an unsername "hans" and his password "helmihelmihelmi".
Here my setup:
web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<context-param>
<param-name>resteasy.role.based.security</param-name>
<param-value>true</param-value>
</context-param>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Application</realm-name>
</login-config>
<security-role>
<role-name>store</role-name>
</security-role>
</web-app>
(I don't know what security realms are, so I just left this property in the login-config tag)
My security domain in standalone.xml
<security-domain name="DBLogin" cache-type="default">
<authentication>
<login-module code="Database" flag="required">
<module-option name="dsJndiName" value="java:jboss/datasources/ExampleDS"/>
<module-option name="principalsQuery" value="SELECT a.password FROM Account a WHERE a.name = ?"/>
<module-option name="rolesQuery" value="SELECT a.userRole FROM Account a WHERE a.name = ?"/>
<module-option name="hashAlgorithm" value="SHA-256"/>
<module-option name="hashEncoding" value="Base64"/>
<module-option name="hashCharset" value="UTF-8"/>
<module-option name="unauthenticatedIdentity" value="guest"/>
</login-module>
</authentication>
</security-domain>
Restful webservice
@GET
@RolesAllowed(AuthRole.STORE)
@Produces(MediaType.APPLICATION_JSON)
public Response getAccountByName() {
Response.ResponseBuilder builder = Response.ok();
return builder.build();
}
and import.xml to create user on startup
insert into Account(id, name, email, password, user_role) values (0, 'hans', '[email protected]', 'helmihelmihelmi', 'store')
insert into Store(id, name, zipcode, street, housenumber, town, account_id) values(0, 'Edeka', 72622, 'stephanstraße', 10, 'Reudern', 0);
Don't know how to find a solution, because I don't even know the problem. Hope somebody can help.
You mustn't store the unencrypted password in the database. WildFly expects you to store the hashed password, using the hash algorithm and encoding specified in the login-module
configuration.
When creating a new Account
, use
org.jboss.security.auth.spi.Util.createPasswordHash()
to obtain the hashed password to store.
As a rule, storing raw passwords is a security risk.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With