...
- Grouper built-in basic authentication
- Grouper LDAP authentication
- Tomcat authentication
- Apache authentication
- Kerberos user/pass
- SSL certificatesCustom authentication
- Rampart (on top of something else)
- SSL certificates. There is no documentation on this. Do this with Apache or Tomcat and pass in the REMOTE_USER.
- other? if you can get a REMOTE user via apache or tomcat plugin or filter, it will work with Grouper WS
Types of subject sources
When the authentication happens and the principal name is given to Grouper from the authentication source, it needs to be resolvable as a subject. There are a few options
...
Code Block |
---|
# If there is an entry here for group name, then all web service client users must be in this group (before the actAs)
#ws.client.user.group.name = etc:webServiceClientUsers
# allow these ids even if not in group, e.g. for testing
# subjectIdOrIdentifier or sourceId::::subjectId or ::::subjectId or sourceId::::::subjectIdentifier or ::::::subjectIdentifier
# sourceId::::::::subjectIdOrIdentifier or ::::::::subjectIdOrIdentifier
# {valueType: "subject", multiple: true}
ws.client.user.group.subjects.allow =
# cache the decision to allow a user to user web services, so it doesnt have to be calculated each time
# defaults to 5 minutes:
# {valueType: "integer", required: true}
ws.client.user.group.cache.minutes = 5
# if you have subject namespace overlap (or not), set the default subject
# sources (comma-separated) to lookup the user if none specified in user name
# {valueType: "string"}
ws.logged.in.subject.default.source =
# prepend to the userid this value (e.g. if using local entities, might be: etc:servicePrincipals: )
# {valueType: "string"}
ws.security.prependToUserIdForSubjectLookup =
|
HTTP basic with kerberos
Grouper-ws comes with an option to authenticate REST or SOAP with HTTP basic auth, but using the user/pass to authenticate to a kerberos kdc. This exists so that kerberos can be used with REST (for SOAP, ws-security would be more secure), and as an example of how to customize the authentication. You should use SSL if you use this authentication. This defeats the purpose of kerberos since it transmits the password over the wire, and it only authenticates to the kdc and not an SSL service, so it might be possible for someone to spoof the kdc. To use this, make the following settings in the grouper-ws.properties (obviously you need to configure the kerberos settings to fit your institution):
No Format |
---|
# to provide custom authentication (instead of the default httpServletRequest.getUserPrincipal()
# for non-Rampart authentication. Class must implement the interface:
# edu.internet2.middleware.grouper.ws.security.WsCustomAuthentication
# class must be fully qualified. e.g. edu.school.whatever.MyAuthenticator
# blank means use default: edu.internet2.middleware.grouper.ws.security.WsGrouperDefaultAuthentication
ws.security.non-rampart.authentication.class = edu.internet2.middleware.grouper.ws.security.WsGrouperKerberosAuthentication
################# KERBEROS settings, only needed if doing kerberos simple auth ################
# realm, whatever your realm is, e.g. SCHOOL.EDU
kerberos.realm = SCHOOL.EDU
# address of your kdc, e.g. kdc.school.edu
kerberos.kdc.address = kdc.school.edu
|
Custom authentication plugin
If you want custom authentication (e.g. pass in a token, and decode it), then implement the interface edu.internet2.middleware.grouper.ws.security.WsCustomAuthentication and configure your fully qualified classname in the grouper-ws.properties. The default is an implementation of this interface as an example: edu.internet2.middleware.grouper.ws.security.WsGrouperDefaultAuthentication, which just gets the user from the container: httpServletRequest.getUserPrincipal().getName()
Rampart
Rampart is Jakarta's WS-Security implementation. We have vanilla Rampart authentication working with grouper-ws (thanks to Sanjay Vivek). Unfortunately it doesnt work out of the box since it seems Rampart and basic auth cannot work together in the web app. If you want to run basic auth and rampart at the same time, you should deploy two separate web apps.
Note the URL for rampart in grouper-ws is the same, it will look like this: /grouper-ws/services/GrouperService
Also, for Rampart, you need custom logic to authenticate users. To use rampart, configure the grouper-ws.properties entry: ws.security.rampart.authentication.class. An example is: edu.internet2.middleware.grouper.ws.security.GrouperWssecSample. Until you configure that, clients will get a 404 http status code. This assumes you are using WSPasswordCallback, if not, just provide your own class directly to the services.xml file (and grouper-ws requires you have an implementation of the interface anyway which wont be executed).
You need to tell grouper that wssec is enabled in the web.xml servlet param (uncomment):
No Format |
---|
<servlet>
<servlet-name>AxisServlet</servlet-name>
<display-name>Apache-Axis Servlet</display-name>
<servlet-class>edu.internet2.middleware.grouper.ws.GrouperServiceAxisServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<!-- hint that this is the wssec servlet -->
<init-param>
<param-name>wssec</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
|
Also you need to comment out the container auth in web.xml:
No Format |
---|
<!-- security-constraint>
<web-resource-collection>
<web-resource-name>Web services</web-resource-name>
<url-pattern>/services/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>grouper_user</role-name>
</auth-constraint>
</security-constraint -->
|
Then you need to enable the correct .aar file.
- If you are using a binary grouper-ws.war, just rename the following two files
- /WEB-INF/services/GrouperService.aar to /WEB-INF/services/GrouperService.aar.ondeck
- /WEB-INF/services/GrouperServiceWssec.aar.ondeck to /WEB-INF/services/GrouperServiceWssec.aar
- If you are building, just set the param in the build.properties: webapp.authentication.use.rampart
Here is a sample client
HTTP basic authentication (use)
In the web.xml for the grouper-ws project, protect all services:
No Format |
---|
<security-constraint> <web-resource-collection> <web-resource-name>Web services</web-resource-name> <url-pattern>/services/*</url-pattern> </web-resource-collection> <auth-constraint> <!-- NOTE: This role is not present in the default users file --> <role-name>grouper_user</role-name> </auth-constraint> </security-constraint> <!-- Define the Login Configuration for this Application --> <login-config> <auth-method>BASIC</auth-method> <realm-name>Grouper Application</realm-name> </login-config> <!-- Security roles referenced by this web application --> <security-role> <description> The role that is required to log in to the Manager Application </description> <role-name>grouper_user</role-name> </security-role> </web-app> |
Now send the user and pass in the web service client.
Here is an example with Axis generated clients:
No Format |
---|
GrouperServiceStub stub = new GrouperServiceStub( "http://localhost:8090/grouper-ws/services/GrouperService"); Options options = stub._getServiceClient().getOptions(); HttpTransportProperties.Authenticator auth = new HttpTransportProperties.Authenticator(); auth.setUsername("user"); auth.setPassword("pass"); options.setProperty(HTTPConstants.AUTHENTICATE, auth); |
Here is an example with a manual HttpClient:
No Format |
---|
HttpClient httpClient = new HttpClient();
GetMethod getMethod = new GetMethod(
"http://localhost:8091/grouper-ws/services/GrouperService/addMemberSimple?groupName=aStem:aGroup&subjectId=10021368&actAsSubjectId=GrouperSystem");
httpClient.getParams().setAuthenticationPreemptive(true);
Credentials defaultcreds = new UsernamePasswordCredentials("user", "pass");
httpClient.getState().setCredentials(new AuthScope("localhost", 8091), defaultcreds);
httpClient.executeMethod(getMethod);
|
ActAs configuration
To enable web service users to act as another user (proxy), enable the setting in the grouper-ws grouper.properties
...