Central Authorization System
Download
Report
Transcript Central Authorization System
Grouper
Web
Services
Java Web Service Servers and
Clients in Internet2 Grouper
February 2009
Chris Hyzer
University of Pennsylvania IT
Internet2
GrouperWeb
WebServices
Services
Grouper
Purpose of this presentation
Show how Internet2 Grouper developed web services
Grouper is open source, feel free to borrow or suggest
improvements
Discuss the successes and areas for improvement
Mention planned enhancements
7/17/2015
University of Pennsylvania
2
GrouperWeb
WebServices
Services
Grouper
Contents
Introduction to Internet2 Grouper
Introduction to web services
Architecture of REST/SOAP web service
SOAP web services with Axis2 (servers and clients)
REST web services with xstream (servers and clients)
Client
Documenting web services
Bonus material
– Security
– Axis serving Rest
– Testing
7/17/2015
University of Pennsylvania
3
Grouper Web Services
INTRODUCTION TO
INTERNET2 GROUPER
7/17/2015
University of Pennsylvania
4
GrouperWeb
WebServices
Services
Grouper
Internet2 Grouper
Open source group management
Internet2 has been working on group management for 8 years
Generally used in educational institutions, but could be
anywhere
Funded by Internet2
7/17/2015
University of Pennsylvania
5
GrouperWeb
WebServices
Services
Grouper
Why central group management with Grouper?
Instead of apps managing own groups
Reuse group lists
Central place to see which groups a person is in
Central auditing of group and membership actions
Central management of authorization
Security:
– Who can view/edit groups and memberships
– Opt-in/Opt-out
– Delegate authority
Automatic or manual membership management
Composite groups for group match: and / or / minus
Groups of groups
7/17/2015
University of Pennsylvania
6
GrouperWeb
WebServices
Services
Grouper
Grouper architecture
7/17/2015
University of Pennsylvania
7
Grouper Web Services
INTRODUCTION TO
WEB SERVICES
7/17/2015
University of Pennsylvania
8
GrouperWeb
WebServices
Services
Grouper
User web request
Person using browser makes a request to a server
Person (user) views the results in browser, and types and or
clicks to continue
7/17/2015
University of Pennsylvania
9
GrouperWeb
WebServices
Services
Grouper
Web service request
Program makes a request to a web application
Program parses the output
7/17/2015
University of Pennsylvania
10
GrouperWeb
WebServices
Services
Grouper
Overlap of web request and web service?
Ajax for example
– Can be kicked off by a user click
– Can update the screen similar to a web application
– However, Ajax is making the request and parsing the response, it is a
web service
– If it doesn’t parse the output, and just puts the resultant HTML into the
browser DOM, then not a web service
Web service screen scraping a web application
– A program can “screen scrape” a web application
– Beware of changes in the HTML!
– This is not a web service
Is a browser an application making requests, are all user
requests web services?
7/17/2015
University of Pennsylvania
11
GrouperWeb
WebServices
Services
Grouper
Why web services
http(s) is a well understood protocol by programming
languages and programmers
Ports 80/443 might already be available in firewall rules
Http is text based (easy to debug)
Http is not programming language specific, so the server
technology can be different than the client (e.g. ajax)
Webpages are either XML, XHTML, or XML-like (e.g. HTML)
– Most programming languages have XML libraries
– Note: web services do not have to be XML, though generally the are
Development and production environments might be similar
(or same) to existing web applications
Penn generally communicates between systems with WS
7/17/2015
University of Pennsylvania
12
GrouperWeb
WebServices
Services
Grouper
SOAP web services
Simple Object Access Protocol
Specifies how web service messages are exchanged
W3C standard
Must use XML and XML schema for data
Messages have XML envelopes, headers, body, exception
handling
Web Service Description Language (WSDL) describes the
SOAP messages in a programmatic way (XML)
Many features (security, error handling, caching, resource
discovery, etc)
Many programming languages generate SOAP
Not considered light-weight
7/17/2015
University of Pennsylvania
13
GrouperWeb
WebServices
Services
Grouper
Example SOAP request
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope
xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Body>
<ns1:addMemberLite
xmlns:ns1="http://soap.ws.grouper.middleware.internet2.edu/
xsd">
<ns1:groupName>aStem:aGroup</ns1:groupName>
<ns1:subjectIdentifier>mchyzer</ns1:subjectIdentifier>
</ns1:addMemberLite>
</soapenv:Body>
</soapenv:Envelope>
7/17/2015
University of Pennsylvania
14
GrouperWeb
WebServices
Services
Grouper
REST web services
Representational State Transfer
Two definitions:
1. (strict or RESTful): Protocol that specifies how HTTP (perhaps) and
XML are used for web services
2. (non-strict): Any web service that does not have the overhead of
SOAP. Aka Remote Procedure Call (RPC)
7/17/2015
University of Pennsylvania
15
GrouperWeb
WebServices
Services
Grouper
RESTful web services
The web services are organized like static web resources
URL’s represent resources, not operations
HTTP methods indicate the operations. Generally: GET,
POST (update), PUT (insert), DELETE. Can use more, or
custom
Messages can be HTML so that systems or browsers can
consume them
7/17/2015
University of Pennsylvania
16
GrouperWeb
WebServices
Services
Grouper
Example REST web service
PUT
/grouperWs/servicesRest/xhtml/v1_4_000/groups/aStem%3A
aGroup/members/mchyzer
This means add this member to the group
7/17/2015
University of Pennsylvania
17
GrouperWeb
WebServices
Services
Grouper
HTTP / XML / RPC / Hybrid web services
Each service makes its own standards
URL can be:
– Resource: http://localhost/grouperWs/group
– Operation: http://localhost/grouperWs/addGroup
Generally just use POST or GET as the HTTP method
The XML document sent can be:
– Complete object representation:
<group><name>myGroup</name><desc>MyGroup</desc></group>
– Operational:
<groupChangeName><groupId>123</groupId>
<newName>myGroup2</newName></groupChangeName>
7/17/2015
University of Pennsylvania
18
Grouper Web Services
GROUPER WEB SERVICES
7/17/2015
University of Pennsylvania
19
GrouperWeb
WebServices
Services
Grouper
Grouper web services
Generally web services are programmed to host a service
Grouper is software, so its WS are programmed so institutions
can download and host services
E.g. Grouper is app server and database server agnostic
Requirements
–
–
–
–
–
–
–
Dozen operations
SOAP and REST (as close to RESTful as possible)
SOAP and REST should deploy in one webapp
Simple operations (Lite), and batched operations
Pluggable authentication
Documented well
Versioned (generally Grouper has bi-annual releases)
7/17/2015
University of Pennsylvania
20
GrouperWeb
WebServices
Services
Grouper
Grouper web service operations
addMember
deleteMember
getMembers
hasMember
getGroups
groupSave
groupDelete
7/17/2015
findGroups
findStems
stemSave
stemDelete
memberChangeSubject
getGrouperPrivileges
assignGrouperPrivileges
University of Pennsylvania
21
GrouperWeb
WebServices
Services
Grouper
Lite vs batched
One batched operation has less overhead than many smaller
operations (performance test for yourself to validate)
Benchmarks
– Add group (inserts), requires many queries
• 100 batches of 1 add groups take 19.8 seconds
• 10 batches of 10 add groups take 12.4 seconds
• 5 batches of 20 add groups take 12.0 seconds
– Has member, lightweight, readonly
• 100 batches of 1 hasMember checks take 8.3 seconds
• 10 batches of 10 checks take 1.9 seconds
• 5 batches of 20 checks take 1.6 seconds
Benchmarks notes
– Completely run on developer PC, local mysql
– E.g. WsSampleHasMemberRest100
7/17/2015
University of Pennsylvania
22
GrouperWeb
WebServices
Services
Grouper
Object model
Assume web service data are simple POJOs (Plain Old Java
Objects)
Use only:
– Beans
– Arrays (of beans or simple types)
– Simple types: String, Integer
Note:
– Don’t use Collections, enums, dates, timestamps, booleans
7/17/2015
University of Pennsylvania
23
GrouperWeb
WebServices
Services
Grouper
Object model (continued)
What makes up the data of a group?
Here is a simple group
7/17/2015
University of Pennsylvania
24
GrouperWeb
WebServices
Services
Grouper
Object model (continued)
What makes up the data of a group?
Here is a more complex group
7/17/2015
University of Pennsylvania
25
GrouperWeb
WebServices
Services
Grouper
Object model (continued)
7/17/2015
University of Pennsylvania
26
GrouperWeb
WebServices
Services
Grouper
Object model (continued)
Request object model
7/17/2015
University of Pennsylvania
27
GrouperWeb
WebServices
Services
Grouper
Object model (continued)
Response object model
7/17/2015
University of Pennsylvania
28
GrouperWeb
WebServices
Services
Grouper
Object model (continued)
Metadata object model
Response metadata is one per response
Result metadata is one per Lite response, or one per each
line item in batch
Success: T|F
Result code:
many enums
Codes also in
HTTP headers
7/17/2015
University of Pennsylvania
29
GrouperWeb
WebServices
Services
Grouper
Object model (continued)
Operations should be idempotent if possible
– If they are sent twice, generally it is ok
Delete member mchyzer from group etc:sysAdminGroup
– Idempotent
Delete the first member of group etc:sysAdminGroup
– NOT idempotent
7/17/2015
University of Pennsylvania
30
Grouper Web Services
SOAP WEB SERVICES WITH
AXIS2
7/17/2015
University of Pennsylvania
31
GrouperWeb
WebServices
Services
Grouper
Axis architecture
7/17/2015
University of Pennsylvania
32
GrouperWeb
WebServices
Services
Grouper
Business logic for Axis
Create a class (GrouperService)
Contains only instance methods of business logic
Each method takes all fields of the input bean, and returns the
output bean
Each bean is only simple pojo (uses Javabean properties)
Note the Lite methods only take scalars are inputs
7/17/2015
University of Pennsylvania
33
GrouperWeb
WebServices
Services
Grouper
Business logic for Axis (continued)
7/17/2015
University of Pennsylvania
34
GrouperWeb
WebServices
Services
Grouper
Business logic for Axis (continued)
GrouperService isn’t great for Javadoc since enums are
strings
Delegate to GrouperServiceLogic
Decode booleans, dates, enums, etc
7/17/2015
University of Pennsylvania
35
GrouperWeb
WebServices
Services
Grouper
Axis generate WSDL
Generate WSDL from POJOs and GrouperService class
<target name="java2wsdl" description="convert the java to a wsdl">
<touch file="${generated.client.project.dir}/GrouperService.wsdl" />
<delete file="${generated.client.project.dir}/GrouperService.wsdl" />
<java classname="org.apache.ws.java2wsdl.Java2WSDL" fork="true">
<classpath refid="ws.class.path" />
<arg value="-o" /><arg value="${generated.client.project.dir}" />
<arg value="-of" /><arg value="GrouperService.wsdl" />
<arg value="-cn" />
<arg value="edu.internet2.middleware.grouper.ws.soap.GrouperService" />
<arg value="-stn" />
<arg value="http://soap.ws.grouper.middleware.internet2.edu/xsd" />
<arg value="-l" />
<arg value="http://localhost:8090/grouper-ws/services/GrouperService" />
</target>
7/17/2015
University of Pennsylvania
36
GrouperWeb
WebServices
Services
Grouper
Axis generate WSDL (continued)
Generate WSDL from POJOs and GrouperService class
C:\dev_inst\eclipse\workspace\grouper_v1_4\grouper-ws>ant java2wsdl
Buildfile: build.xml
java2wsdl:
[delete] Deleting: C:\dev_inst\eclipse\workspace\grouper_v1_4\grouper-ws-java
-generated-client\GrouperService.wsdl
BUILD SUCCESSFUL
Total time: 9 seconds
C:\dev_inst\eclipse\workspace\grouper_v1_4\grouper-ws>
7/17/2015
University of Pennsylvania
37
GrouperWeb
WebServices
Services
Grouper
Axis generate WSDL (continued)
Result
7/17/2015
University of Pennsylvania
38
GrouperWeb
WebServices
Services
Grouper
Axis generate WSDL (continued)
Result – 2000 lines of SOAP definition
7/17/2015
University of Pennsylvania
39
GrouperWeb
WebServices
Services
Grouper
Axis generate client
Ant script to generate SOAP client from WSDL (any WSDL)
<target name="wsdl2java" description="convert the wsdl to a java client">
<delete><fileset dir="${generated.client.project.dir}">
<include name=“…” /></fileset></delete>
<java classname="org.apache.axis2.wsdl.WSDL2Java" fork="true">
<classpath refid="ws.class.path" />
<arg value="-uri" />
<arg file="${generated.client.project.dir}/GrouperService.wsdl" />
<arg value="-t" /><arg value="-u" /><arg value="-p" />
<arg value="edu.internet2.middleware.grouper.webservicesClient" />
<arg value="-o" /><arg value="${generated.client.project.dir}" />
</java>
</target>
7/17/2015
University of Pennsylvania
40
GrouperWeb
WebServices
Services
Grouper
Axis generate client (continued)
Run ant script to generate client
C:\dev_inst\eclipse\workspace\grouper_v1_4\grouper-ws>ant wsdl2java
Buildfile: build.xml
wsdl2java:
[java] Retrieving document at 'C:\dev_inst\eclipse\workspace\grouper_v1_4\g
rouper-ws-java-generated-client\GrouperService.wsdl'.
BUILD SUCCESSFUL
Total time: 9 seconds
C:\dev_inst\eclipse\workspace\grouper_v1_4\grouper-ws>
7/17/2015
University of Pennsylvania
41
GrouperWeb
WebServices
Services
Grouper
Axis generate client (continued)
Result: 100 classes, ~5megs of source
7/17/2015
University of Pennsylvania
42
GrouperWeb
WebServices
Services
Grouper
Axis archive
Axis needs an AAR file of logic, create via ant to WEBINF/services/GrouperService.aar
<target name="generate-aar" depends="compile">
<property name="webservice.folder" value="${basedir}/webservices" />
<delete dir="${webservice.folder}/classes" />
<copy toDir="${webservice.folder}/classes" failonerror="false">
<fileset dir="${build.dir.grouper-ws}">
<include name="edu/internet2/middleware/grouper/ws/**/*.class" />
</fileset></copy>
<jar destfile="${basedir}/webapp/WEB-INF/services/GrouperService.aar">
<fileset excludes="edu/internet2/middleware/grouper/ws/**/*Test.class"
dir="${webservice.folder}/classes" />
<fileset dir="webservices/GrouperService.aar" />
</jar>
</target>
7/17/2015
University of Pennsylvania
43
GrouperWeb
WebServices
Services
Grouper
Axis configuration
Configure the web.xml for Axis
<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>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
7/17/2015
University of Pennsylvania
44
GrouperWeb
WebServices
Services
Grouper
Axis configuration (continued)
Boilerplate WEB-INF/conf/axis2.xml
WEB-INF/modules/*.mar
WEB-INF/modules/modules.list
WEB-INF/services/*.aar (including
GrouperService.aar)
WEB-INF/service/services.list
WEB-INF/lib/ (50 axis jars)
7/17/2015
University of Pennsylvania
45
GrouperWeb
WebServices
Services
Grouper
Axis Example
See video (make sure you have the Xvid codec):
https://wiki.internet2.edu/confluence/download/attachments/3
014660/soapExample.avi
7/17/2015
University of Pennsylvania
46
Grouper Web Services
REST WEB SERVICES WITH
XSTREAM
7/17/2015
University of Pennsylvania
47
GrouperWeb
WebServices
Services
Grouper
Xstream
Easy to use Java object to XML processor
In this example I alias the class names so they arent so long
public class XstreamPocGroup {
public XstreamPocGroup(String theName, XstreamPocMember[]
theMembers) {
this.name = theName;
this.members = theMembers;
}
private String name;
private XstreamPocMember[] members;
public String getName() {
...
7/17/2015
University of Pennsylvania
48
GrouperWeb
WebServices
Services
Grouper
Xstream (continued)
This is the child bean
public class XstreamPocMember {
public XstreamPocMember(String theName, String
theDescription) {
this.name = theName;
this.description = theDescription;
}
private String name;
private String description;
}
7/17/2015
University of Pennsylvania
49
GrouperWeb
WebServices
Services
Grouper
Xstream (continued)
public static void main(String[] args) {
XstreamPocGroup group = new XstreamPocGroup("myGroup",
new XstreamPocMember[]{
new XstreamPocMember("John", "John Smith - Employee"),
new XstreamPocMember("Mary", "Mary Johnson - Student")});
XStream xStream = new XStream(new XppDriver());
xStream.alias("XstreamPocGroup", XstreamPocGroup.class);
xStream.alias("XstreamPocMember", XstreamPocMember.class);
StringWriter stringWriter = new StringWriter();
xStream.marshal(group, new CompactWriter(stringWriter));
String xml = stringWriter.toString();
System.out.println(GrouperUtil.indent(xml, true));
group = (XstreamPocGroup)xStream.fromXML(xml);
System.out.println(group.getName() + ", number of members:"
+ group.getMembers().length); }
7/17/2015
University of Pennsylvania
50
GrouperWeb
WebServices
Services
Grouper
Xstream (continued)
<XstreamPocGroup>
<name>myGroup</name>
<members>
<XstreamPocMember>
<name>John</name>
<description>John Smith - Employee</description>
</XstreamPocMember>
<XstreamPocMember>
<name>Mary</name>
<description>Mary Johnson - Student</description>
</XstreamPocMember>
</members>
</XstreamPocGroup>
myGroup, number of members: 2
7/17/2015
University of Pennsylvania
51
GrouperWeb
WebServices
Services
Grouper
Xstream JSON
You can control things with annotations
@XStreamOmitField
private Group group = null;
You can convert Java object to JSON
XStream xStream = new XStream(new
JettisonMappedXmlDriver());
{"XstreamPocGroup":
{"name":"myGroup","members":
{"XstreamPocMember":[
{"name":"John","description":"John Smith - Employee"},
{"name":"Mary","description":"Mary Johnson - Student"}
]}}
}
myGroup, number of members: 2
7/17/2015
University of Pennsylvania
52
GrouperWeb
WebServices
Services
Grouper
XHTML output
Grouper had a requirement to have XHTML output
Rest people like XHTML, it can turn a web service into a
browsable application
– I have some reservations about that (what are the clients? Browsers,
or screen scraping applications? Can you change the output?)
I rolled my own bean->XHTML converter
Based on XmlStreamWriter for output
Based on JDOM for input
7/17/2015
University of Pennsylvania
53
GrouperWeb
WebServices
Services
Grouper
XHTML output (continued)
WsXhtmlOutputConverter wsXhtmlOutputConverter = new
WsXhtmlOutputConverter(true, null);
StringWriter stringWriter = new StringWriter();
wsXhtmlOutputConverter.writeBean(group, stringWriter);
String xhtml = stringWriter.toString();
System.out.println(GrouperUtil.indent(xhtml, true));
WsXhtmlInputConverter wsXhtmlInputConverter = new WsXhtmlInputConverter();
wsXhtmlInputConverter.addAlias("XstreamPocGroup", XstreamPocGroup.class);
wsXhtmlInputConverter.addAlias("XstreamPocMember",
XstreamPocMember.class);
group = (XstreamPocGroup)wsXhtmlInputConverter.parseXhtmlString(xhtml);
System.out.println(group.getName() + ", number of members: "
+ group.getMembers().length);
7/17/2015
University of Pennsylvania
54
GrouperWeb
WebServices
Services
Grouper
XHTML output (continued)
<?xml version='1.0' encoding='iso-8859-1'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
lang="en">
<head>
<title>XstreamPocGroup</title>
</head>
<body>
<div title="XstreamPocGroup">
<ul class="members">
<li title="XstreamPocMember">
<p class="name">John</p>
<p class="description">John Smith - Employee</p>
</li>
7/17/2015
University of Pennsylvania
55
GrouperWeb
WebServices
Services
Grouper
XHTML output (continued)
<li title="XstreamPocMember">
<p class="name">Mary</p>
<p class="description">Mary Johnson - Student</p>
</li>
</ul>
<p class="name">myGroup</p>
</div>
</body>
</html>
myGroup, number of members: 2
Note: Im not sure why this would be useful…
7/17/2015
University of Pennsylvania
56
GrouperWeb
WebServices
Services
Grouper
HTTP input
Similar to Axis input, REST (Lite) should accept HTTP params
(URL params or in HTTP body)
PUT /grouperWs/servicesRest/v1_4_000/groups
/aStem%3AaGroup/members/10021368 HTTP/1.1
Connection: close
Authorization: Basic xxxxxxxxxxxxxxxxx==
User-Agent: Jakarta Commons-HttpClient/3.1
Host: localhost:8092
Content-Length: 72
wsLiteObjectType=WsRestAddMemberLiteRequest
&actAsSubjectId=GrouperSystem
7/17/2015
University of Pennsylvania
57
GrouperWeb
WebServices
Services
Grouper
Indenting of XML, XHTML, JSON
Couldn’t find a 3rd party indenter, rolled my own
System.out.println(GrouperUtil.indent(xhtml, true));
System.out.println(GrouperUtil.indent(json, true));
System.out.println(GrouperUtil.indent(xml, true));
This is valuable when showing examples
7/17/2015
University of Pennsylvania
58
GrouperWeb
WebServices
Services
Grouper
Make the operations more Restful
URLs need to represent hierarchical resources:
/servicesRest/v1_4_000/groups/aStem%3AaGroup/members
–
–
–
–
–
–
Servlet, client version, top level “folder”, name of item, inner “folder”
The client version is in there since that is the first part of versioning
GET that URL would retrieve all the members of that group
POST would update the list (send all new members)
PUT would create a new list
DELETE would delete all the members
…/groups/aStem%3AaGroup/members/mchyzer
–
–
–
–
Drilling down further
GET could see if mchyzer is a member
PUT would add mchyzer to group
etc
7/17/2015
University of Pennsylvania
59
GrouperWeb
WebServices
Services
Grouper
Problems with Rest
Some things are programmatic, not resource based (e.g. a
fixBadMemberships diagnostic tool)
The input params could be complicated, e.g.
–
–
–
–
Get the membership list of a group
Get only immediate members
Act as a different user (proxy)
Get the student list, not the faculty list
There might be many different ways to ID a resource
– E.g. name or UUID
Composite ID’s of resources are not convenient
– /groups/aStem:aGroup/members/sourceId/someSource/subjectId/1234
7/17/2015
University of Pennsylvania
60
GrouperWeb
WebServices
Services
Grouper
Problems with Rest (continued)
The only HTTP methods which take a body are POST and
PUT
– How can you delete something with XML constraints (actAs proxy,
certain list type, include details on result) if a DELETE method does
not take an XML body???
Rest is supposed to “model the web”
– Which web? Static? When is the last time you deleted a static
resource with an HTTP DELETE method?
– The web is more and more dynamic, so Rest/HTTP/XML/hybrid might
be more similar for developers
7/17/2015
University of Pennsylvania
61
GrouperWeb
WebServices
Services
Grouper
Grouper Rest
URLs are resource based
HTTP methods are honored (GET/POST/PUT/DELETE)
If there is a body (POST/PUT), then the object type sent will
trump the HTTP method (can DELETE with metadata)
HTTP status codes are sent
– Though they really shouldn’t be read, they don’t mean much, 404 could
be a success
HTTP headers on the response
– boolean to determine if the operation is a success or failure
– Enum based text status code which is specific to the operation
7/17/2015
University of Pennsylvania
62
GrouperWeb
WebServices
Services
Grouper
Grouper Rest (continued)
The same operations are exposed as SOAP
The XML document can specify the data, or the URL/HTTP
method
Could add member like this:
PUT /grouperWs/servicesRest/xhtml/v1_4_000
/groups/aStem%3AaGroup/members/10021368 HTTP/1.1
Or you could add a member with a POST and a body of the
right object type:
POST /grouperWs/servicesRest/v1_4_001/groups
/aStem%3AaGroup/members HTTP/1.1
<WsRestAddMemberLiteRequest><subjectId>10021368</subjectId>
<actAsSubjectId>GrouperSystem</actAsSubjectId>
</WsRestAddMemberLiteRequest>
7/17/2015
University of Pennsylvania
63
GrouperWeb
WebServices
Services
Grouper
Grouper Rest Architecture
7/17/2015
University of Pennsylvania
64
GrouperWeb
WebServices
Services
Grouper
Grouper Rest (continued)
Client can use same beans as server (not true with Axis)
Enums for content types
Use Jakarta HTTP client for communication (Axis uses this
too)
Show movie of Rest client (make sure you have the Xvid
codec):
https://wiki.internet2.edu/confluence/download/attachments/3
014660/restDemo.avi
7/17/2015
University of Pennsylvania
65
Grouper Web Services
WHICH WEB SERVICE
ARCHITECTURE SHOULD I USE?
7/17/2015
University of Pennsylvania
66
GrouperWeb
WebServices
Services
Grouper
When SOAP
More complex operations (describe in WSDL)
Clients can handle SOAP
Client code generation
WS-* security (e.g. kerberos ticket authentication)
7/17/2015
University of Pennsylvania
67
GrouperWeb
WebServices
Services
Grouper
When Restful
Simple operations
– Non batched
Simple resources
– Nice to not have composite identifiers
Operations with little or no metadata (e.g. actAs)
Clients are known to handle Rest HTTP methods
Perhaps not for Ajax (limitation might be HTTP response code
and HTTP methods)
7/17/2015
University of Pennsylvania
68
GrouperWeb
WebServices
Services
Grouper
When Rest / HTTP / XML hybrid / POX
When supporting “Rest” and SOAP
– Since SOAP is not resource based
Disparate clients
Need to send a body of metadata with a GET or DELETE
7/17/2015
University of Pennsylvania
69
Grouper Web Services
CLIENT
7/17/2015
University of Pennsylvania
70
GrouperWeb
WebServices
Services
Grouper
GrouperClient
Architecture
7/17/2015
University of Pennsylvania
71
GrouperWeb
WebServices
Services
Grouper
GrouperClient
Its nice to give a packaged client with web services
Writing HTTP/XML does not make a quick start
Anyone can use it command line
Can use as Java library
Can make custom XML samples
Debugging tools
More samples
Rest only (since easiest to version, most lightweight… doesn’t
have 50 Axis jars!)
Since command line, its one jar
Can be used along side other jars
7/17/2015
University of Pennsylvania
72
GrouperWeb
WebServices
Services
Grouper
GrouperClient (continued)
Very simple POJOs
Refactor 3rd party libs
–
–
–
–
–
Xstream
HttpClient
Commons-logging
Jexl: expression language
morphString
So they don’t conflict
Want only one jar
7/17/2015
University of Pennsylvania
73
GrouperWeb
WebServices
Services
Grouper
GrouperClient (continued)
Example:
C:\gc>java -jar grouperClient.jar --operation=getGroupsWs
--subjectIds=10021368
SubjectIndex 0: success: T: code: SUCCESS: subject:
10021368: groupIndex: 0: aStem:aGroup
SubjectIndex 0: success: T: code: SUCCESS: subject:
10021368: groupIndex: 1: etc:webServiceClientUsers
SubjectIndex 0: success: T: code: SUCCESS: subject:
10021368: groupIndex: 2: etc:sysadmingroup
Show movie (make sure you have the Xvid codec):
https://wiki.internet2.edu/confluence/download/attachments/301
4660/grouperClient.avi
7/17/2015
University of Pennsylvania
74
GrouperWeb
WebServices
Services
Grouper
GrouperClient (continued)
Java API
No longer need to deal with httpClient or authentication
Error handling built in
public static void main(String[] args) {
WsGetGroupsResults wsGetGroupsResults = new GcGetGroups()
.addSubjectLookup(new WsSubjectLookup("10021368", null,
null)).execute();
WsGetGroupsResult wsGroupsResult =
wsGetGroupsResults.getResults()[0];
for (WsGroup wsGroup : wsGroupsResult.getWsGroups()) {
System.out.println(wsGroup.getName()); } }
aStem:aGroup
etc:webServiceClientUsers
etc:sysadmingroup
7/17/2015
University of Pennsylvania
75
GrouperWeb
WebServices
Services
Grouper
GrouperClient – external encrypted passwords
Set encrypt key in grouper.client.properties
encrypt.key = fnh453hfbdw
Encrypt the password:
C:\gc>java -jar grouperClient.jar --operation=encryptPassword
Type the string to encrypt (note: pasting might echo it back):
Encrypted password: mpAdW53ekchSGAX3vq1UiQ==
C:\gc>
Put this in a file, refer to file in grouper.client.properties
grouperClient.webService.password = c:/gc/ws.pass
(more) sanitized config files for email or source control
Perhaps auditing requirement forbidding clear text passwords
7/17/2015
University of Pennsylvania
76
GrouperWeb
WebServices
Services
Grouper
GrouperClient – JEXL output templates
If using command line utility in prod, will screenscrape
STDOUT
C:\gc>java -jar grouperClient.jar --operation=getGroupsWs
--subjectIds=10021368
SubjectIndex 0: success: T: code: SUCCESS: subject: 10021368:
groupIndex: 0: aStem:aGroup
To give flexibility, and ability to change defaults, template
C:\gc>java -jar grouperClient.jar --operation=getGroupsWs
--subjectIds=10021368 -–outputTemplate
="${groupIndex+1} groupName: ${wsGroup.name}$newline$"
1 groupName: aStem:aGroup
2 groupName: etc:webServiceClientUsers
3 groupName: etc:sysadmingroup
7/17/2015
University of Pennsylvania
77
GrouperWeb
WebServices
Services
Grouper
Grouper client traffic capture
To help troubleshoot or create samples
grouperClient.logging.webService.documentDir = c:/gc/xmls
grouperClient.logging.webService.indent = true
Organize files so they are easy to archive or delete
7/17/2015
University of Pennsylvania
78
GrouperWeb
WebServices
Services
Grouper
Grouper client traffic capture (continued)
7/17/2015
University of Pennsylvania
79
Grouper Web Services
DOCUMENTING WEB
SERVICES: AUTOMATIC
SAMPLES
7/17/2015
University of Pennsylvania
80
GrouperWeb
WebServices
Services
Grouper
Automatic samples
Samples are tedious to maintain
Too many combinations:
–
–
–
–
Rest and Soap
Lite and Batched
Within Rest: XML, XHTML, JSON, HTTP params
12 operations
Program automatically generates 150+ samples
7/17/2015
University of Pennsylvania
81
GrouperWeb
WebServices
Services
Grouper
Automatic samples (continued)
7/17/2015
University of Pennsylvania
82
GrouperWeb
WebServices
Services
Grouper
Automatic samples
See movie (make sure you have the Xvid codec):
https://wiki.internet2.edu/confluence/download/attachments/3
014660/sampleCapture.avi
7/17/2015
University of Pennsylvania
83
GrouperWeb
WebServices
Services
Grouper
References and links
http://middleware.internet2.edu/dir/groups/grouper/
https://wiki.internet2.edu/confluence/display/GrouperWG/v1.4.
0+Grouper+Web+Services
cvs -d:pserver:[email protected]:/home/cvs/i2mi login
cvs -d:pserver:[email protected]:/home/cvs/i2mi export -r
GROUPER_1_4_BRANCH grouper-ws
http://www.w3schools.com/soap/default.asp
http://en.wikipedia.org/wiki/Representational_State_Transfer
7/17/2015
University of Pennsylvania
84
GrouperWeb
WebServices
Services
Grouper
Questions?
7/17/2015
University of Pennsylvania
85
GrouperWeb
WebServices
Services
Grouper
BONUS MATERIAL: MISC
7/17/2015
University of Pennsylvania
86
GrouperWeb
WebServices
Services
Grouper
Xstream words of warning
The default JSON outputted is awful
– An array of size 1 is the same as a field
– A string with an number value is the same as a number
– If you use this, find settings so that it makes sense
Xstream by default works by fields, not Javabean properties
– This has surfaced from mismatches between Xstream and Axis (which
goes by Javabean properties)
– There is a setting to enable this, it is on my TODO list
You can override some settings in Xstream to ignore
extraneous XML fields (for backwards compatibility)
Fields are lower case, Classes are uppercase (as aliased),
and a user reported difficulty with Xpath
7/17/2015
University of Pennsylvania
87
GrouperWeb
WebServices
Services
Grouper
Grouper Rest (continued)
GrouperRestServlet
<servlet>
<servlet-name>RestServlet</servlet-name>
<display-name>WS REST Servlet</display-name>
<servlet-class>
edu.internet2.middleware.grouper.ws.rest.GrouperRestServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>RestServlet</servlet-name>
<url-pattern>/servicesRest/*</url-pattern>
</servlet-mapping>
7/17/2015
University of Pennsylvania
88
GrouperWeb
WebServices
Services
Grouper
JEXL output templates (continued)
Easy to setup, get jakarta commons jexl.jar
I have a utility method to substitute, something like this:
JexlContext jc = JexlHelper.createContext();
for (String key: variableMap.keySet()) {
jc.getVars().put(key, variableMap.get(key)); }
Pattern pattern = Pattern.compile("\\$\\{(.*?)\\}");
Matcher matcher = pattern.matcher(stringToParse);
StringBuilder result = new StringBuilder();
while(matcher.find()) {
result.append(stringToParse.substring(index,matcher.start()));
String script = matcher.group(1);
Expression e = ExpressionFactory.createExpression(script);
Object o = e.evaluate(jc);
result.append(o);
index = matcher.end(); }
7/17/2015
University of Pennsylvania
89
GrouperWeb
WebServices
Services
Grouper
BONUS MATERIAL: GROUPER
OBJECT MODEL
7/17/2015
University of Pennsylvania
90
GrouperWeb
WebServices
Services
Grouper
Grouper data model (simplified)
7/17/2015
University of Pennsylvania
91
GrouperWeb
WebServices
Services
Grouper
Object model (continued)
How to represent “Group” in a web service pojo?
Where do we need “Group” in web services?
Input examples:
–
–
–
–
–
Add member to a group
Save a group
Delete a group
See if a member is in a group
Find a group
Output examples:
–
–
–
–
List groups for member
Find group
Save a group?
Delete a group?
7/17/2015
University of Pennsylvania
92
GrouperWeb
WebServices
Services
Grouper
Object model (continued)
Break “Group” into two cases
– Lookup
– Object representation
Lookup (allow multiple ways)
– Lookup by UUID
– Lookup by name
– There are several lookups in Grouper WS:
• Stem lookup
• Subject lookup
• Group lookup
How to handle object representation?
7/17/2015
University of Pennsylvania
93
GrouperWeb
WebServices
Services
Grouper
Object model (continued)
Each request has its own object
– One for Lite request
• Note: each Lite request has only scalars
– One for Batch request
Each response has its own object
– One for Lite response
– One for Batch response
– One for each line item of a batch response
7/17/2015
University of Pennsylvania
94
GrouperWeb
WebServices
Services
Grouper
Object model (continued)
Option 1: minimal, make another request for more info
– For list groups for member, send back the group UUID and name
– If more info needed make another request for more info
Option 2: send it all
– Just send everything about a group on all requests
Option 3: pick and choose
– When an operation returns groups, tell the server what to return
Option 4: two levels to decide
– Generally send back basic data
– If includeGroupDetail in a request, send it all
Note: for saveGroup, same object goes back and forth,
including an optional groupLookup on request.
7/17/2015
University of Pennsylvania
95
GrouperWeb
WebServices
Services
Grouper
Lite vs batched (continued)
Original vision was Lite operations would require only scalars
Do not need XML in request
Only use HTTP params
Response would still have a body
Originally we used Axis REST
It didn’t satisfy our requirements, so we moved to custom
REST
7/17/2015
University of Pennsylvania
96
GrouperWeb
WebServices
Services
Grouper
BONUS MATERIAL: AXIS
SERVING REST
7/17/2015
University of Pennsylvania
97
GrouperWeb
WebServices
Services
Grouper
Axis serving Rest
Axis can serve “Rest” services (loose-Rest)
Basically it is the same service without the SOAP envelope
Can also pass params as HTTP params
Set this in axis2.xml:
<parameter name="disableREST"
locked="true">false</parameter>
Set this option in the client:
options.setProperty(
Constants.Configuration.ENABLE_REST,
Constants.VALUE_TRUE);
Show movie (make sure you have the Xvid codec):
https://wiki.internet2.edu/confluence/download/attachments/3
014660/axisRestExample.avi
7/17/2015
University of Pennsylvania
98
GrouperWeb
WebServices
Services
Grouper
Axis serving Rest (continued)
Not clear how to customize the XML, and it is not great
looking XML (not what you would create by hand)
Not real Rest, since the HTTP method is still GET or POST,
not PUT or DELETE
Still resembles RPC calls, not resource centric calls
There is a bad bug with Axis SOAP and REST where if you
skip params it marshals them in the wrong order. Hopefully
this will be fixed soon.
https://issues.apache.org/jira/browse/AXIS2-3364
Grouper abandoned Axis Rest in favor of custom Rest
7/17/2015
University of Pennsylvania
99
GrouperWeb
WebServices
Services
Grouper
BONUS MATERIAL:
WEB SERVICE SECURITY
7/17/2015
University of Pennsylvania
100
GrouperWeb
WebServices
Services
Grouper
Authentication
Easiest way to go is HTTP basic authentication
Assumes using SSL (since only Base64 encoded)
Send this with Commons Http client
httpClient.getParams().setAuthenticationPreemptive(true);
Credentials defaultcreds = new
UsernamePasswordCredentials(RestClientSettings.USER,
RestClientSettings.PASS);
//e.g. localhost and 8093
httpClient.getState()
.setCredentials(new
AuthScope(RestClientSettings.HOST, RestClientSettings.PORT),
defaultcreds);
7/17/2015
University of Pennsylvania
101
GrouperWeb
WebServices
Services
Grouper
Authentication (continued)
Results in this HTTP
PUT
/grouperWs/servicesRest/v1_4_000/groups/aStem
%3AaGroup/members/10021368 HTTP/1.1
Connection: close
Authorization: Basic SDF423SFD423xxxx==
User-Agent: Jakarta Commons-HttpClient/3.1
Host: localhost:8092
Content-Length: 72
7/17/2015
University of Pennsylvania
102
GrouperWeb
WebServices
Services
Grouper
Authentication (continued)
Handle this on the server
Solution should work with Axis or Rest
Make a servlet filter for Soap and Rest:
<filter><filter-name>Grouper service filter</filter-name>
<filter-class>edu.internet2.middleware.grouper.ws.GrouperServiceJ2ee</filterclass></filter>
<filter-mapping>
<filter-name>Grouper service filter</filter-name>
<url-pattern>/services/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Grouper service filter</filter-name>
<url-pattern>/servicesRest/*</url-pattern>
</filter-mapping>
7/17/2015
University of Pennsylvania
103
GrouperWeb
WebServices
Services
Grouper
Authentication (continued)
Keep threadlocals of request and response
threadLocalRequest.set((HttpServletRequest) request);
threadLocalResponse.set((HttpServletResponse) response);
threadLocalRequestStartMillis.set(System.currentTimeMillis());
try {
filterChain.doFilter(request, response);
} finally {
threadLocalRequest.remove();
threadLocalResponse.remove();
threadLocalRequestStartMillis.remove();
}
7/17/2015
University of Pennsylvania
104
GrouperWeb
WebServices
Services
Grouper
Authentication (continued)
Utility method, called from business logic, to authenticate
String authenticationClassName =
GrouperWsConfig.getPropertyString(
GrouperWsConfig.WS_SECURITY_NON_RAMPART_AUTHENTICATION_CLASS,
WsGrouperDefaultAuthentication.class.getName());
Class<? extends WsCustomAuthentication> theClass =
GrouperUtil.forName(authenticationClassName);
WsCustomAuthentication wsAuthentication =
GrouperUtil.newInstance(theClass);
userIdLoggedIn = wsAuthentication
.retrieveLoggedInSubjectId(retrieveHttpServletRequest());
// cant be blank!
if (StringUtils.isBlank(userIdLoggedIn)) {
throw new WsInvalidQueryException("No user is logged in");
}
7/17/2015
University of Pennsylvania
105
GrouperWeb
WebServices
Services
Grouper
Authentication – container authN
Two built in authentication methods, first is container auth
public String retrieveLoggedInSubjectId(HttpServletRequest
httpServletRequest)
throws RuntimeException {
// use this to be the user connected, or the user act-as
String userIdLoggedIn =
GrouperServiceJ2ee.retrieveUserPrincipalNameFromRequest();
return userIdLoggedIn;
}
7/17/2015
University of Pennsylvania
106
GrouperWeb
WebServices
Services
Grouper
Authentication – container authN
Configure in web.xml
<security-constraint><web-resource-collection>
<web-resource-name>Web services</web-resource-name>
<url-pattern>/servicesRest/*</url-pattern>
</web-resource-collection><auth-constraint>
<role-name>grouper_user</role-name>
</auth-constraint></security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Grouper Application</realm-name>
</login-config>
<security-role>
<description>Web service</description>
<role-name>grouper_user</role-name>
</security-role>
7/17/2015
University of Pennsylvania
107
GrouperWeb
WebServices
Services
Grouper
Authentication – container authN (continued)
Configure in tomcat-users.xml (servlet container specific)
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
<role rolename="grouper_user"/>
<user username="mchyzer" password="mchyzer1"
roles="grouper_user"/>
</tomcat-users>
7/17/2015
University of Pennsylvania
108
GrouperWeb
WebServices
Services
Grouper
Authentication – Kerberos
Alternative builtin authentication: Kerberos
String authHeader = request.getHeader("Authorization");
//if no header, we cant go to kerberos
if (StringUtils.isBlank(authHeader)) {
LOG.error("No authorization header in HTTP");
return null;
}
Matcher matcher = regexPattern.matcher(authHeader);
String authHeaderBase64Part = null;
if (matcher.matches()) {
authHeaderBase64Part = matcher.group(1);
}
if (StringUtils.isBlank(authHeaderBase64Part)) {
LOG.error("Cant find base64 part in auth header");
return null; }
7/17/2015
University of Pennsylvania
109
GrouperWeb
WebServices
Services
Grouper
Authentication – Kerberos (continued)
//unencrypt this
byte[] base64Bytes = authHeaderBase64Part.getBytes();
byte[] unencodedBytes = Base64.decodeBase64(base64Bytes);
String unencodedString = new String(unencodedBytes);
//split based on user/pass
String user = GrouperUtil.prefixOrSuffix(unencodedString, ":",
true);
String pass = GrouperUtil.prefixOrSuffix(unencodedString, ":",
false);
if (authenticateKerberos(user, pass)) {
return user;
}
7/17/2015
University of Pennsylvania
110
GrouperWeb
WebServices
Services
Grouper
Authentication – Pluggable
Deployers can use their own authentication
# 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
# kerberos: edu.internet2.middleware.grouper.ws.security
# .WsGrouperKerberosAuthentication
ws.security.non-rampart.authentication.class =
7/17/2015
University of Pennsylvania
111
GrouperWeb
WebServices
Services
Grouper
Authentication – Pluggable
Implement this interface
public interface WsCustomAuthentication {
/**
* retrieve the current username (subjectId) from the request
* object.
* @param httpServletRequest
* @return the logged in username (subjectId)
* @throws WsInvalidQueryException if there is a problem
*/
public String retrieveLoggedInSubjectId(HttpServletRequest
httpServletRequest)
throws WsInvalidQueryException;
}
7/17/2015
University of Pennsylvania
112
GrouperWeb
WebServices
Services
Grouper
Authentication – Caching
It is a TODO to provide the option for the an HTTP basic
authN to cache a hashed version of the authentication
header (and translation to subject ID)
Hash this so a Base64 version is not held in memory
Do not want to load down the authentication service (e.g.
kerberos) if the web service is under high load
7/17/2015
University of Pennsylvania
113
GrouperWeb
WebServices
Services
Grouper
Authentication – Ws- Security
Contributed by Sanjay Vivek at Newcastle University
Axis has a module called Rampart which implements WS –
security standards
Important if the service requires multiple hops or proxying
Useful if not using SSL
Only for Soap, not for Rest
Useful for authenticating without a user/pass (e.g. Kerberos
ticket or x.509)
Cannot run rampart along with HTTP basic authn (need
multiple webapps) in Axis2
7/17/2015
University of Pennsylvania
114
GrouperWeb
WebServices
Services
Grouper
Authentication – Ws- Security (continued)
Set a param in the web.xml
<servlet>
<servlet-name>AxisServlet</servlet-name>
<display-name>Apache-Axis Servlet</display-name>
<servletclass>edu.internet2.middleware.grouper.ws.GrouperServiceAxisS
ervlet</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>wssec</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
7/17/2015
University of Pennsylvania
115
GrouperWeb
WebServices
Services
Grouper
Authentication – Ws- Security (continued)
Configure axis2 GrouperServiceWssec.aar/services.xml
…
<module ref="rampart" />
…
<wsp:Policy>
<sp:HttpsToken RequireClientCertificate="false"/>
</wsp:Policy>
<ramp:RampartConfig
xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:passwordCallbackClass>edu.internet2.middleware.grouper.
ws.security.RampartHandlerServer</ramp:passwordCallbackClass>
</ramp:RampartConfig>
…
7/17/2015
University of Pennsylvania
116
GrouperWeb
WebServices
Services
Grouper
Authentication – Ws- Security (continued)
Default services.xml requires implementation of interface
public interface GrouperWssecAuthentication {
/**
* <pre>
* authenticate the user, and find the subject and return.
* See GrouperWssecSample for an example
* </pre>
* @param wsPasswordCallback
* @return true if callback type is supported, false if not
* @throws IOException if there is a problem or if user is
* not authenticated correctly
*/
public boolean authenticate(WSPasswordCallback
wsPasswordCallback) throws IOException;
}
7/17/2015
University of Pennsylvania
117
GrouperWeb
WebServices
Services
Grouper
Authentication – Ws- Security (continued)
Then you also need to configure this on the client
There is an example in RampartSampleGetGroupsLite.java
Includes service.xml
And RampartPwHandlerClient callback for credentials
7/17/2015
University of Pennsylvania
118
GrouperWeb
WebServices
Services
Grouper
Authorization
Grouper has built in authorization about who is allowed to do
what
–
–
–
–
Who can add to which stems
Who can view memberships
Who can view that groups exist
Who can edit group attributes
Another layer is which users are allowed to use web services
Since Grouper is all about groups, use a group
7/17/2015
University of Pennsylvania
119
GrouperWeb
WebServices
Services
Grouper
Authorization (continued)
Setting in config file lists a group that users must be in to use
WS (if blank allow all)
7/17/2015
University of Pennsylvania
120
GrouperWeb
WebServices
Services
Grouper
Authorization (continued)
If not in group, log it and alert the caller (should make option
to suppress this)
HTTP/1.1 500 Internal Server Error
X-Grouper-resultCode: EXCEPTION
X-Grouper-success: F
<?xml version='1.0' encoding='iso-8859-1'?>
, params: null, java.lang.RuntimeException: User is not
authorized
at edu.internet2…
Caused by: edu.internet2… GroupNotFoundException: Cannot
find group with name: 'etc:webServiceClientUsers'
7/17/2015
University of Pennsylvania
121
GrouperWeb
WebServices
Services
Grouper
Authorization (continued)
Given that callers must be in group, make it easy to setup
This setting in grouper.properties will auto-create groups and
auto-populate for ease of startup and testing
7/17/2015
University of Pennsylvania
122
GrouperWeb
WebServices
Services
Grouper
Authorization (continued)
If there is an auto-created group on startup, log it
2009-02-14 21:28:03,327: [main] WARN
GrouperCheckConfig.checkGroup(130) - cannot find group from
config: grouper.properties key
configuration.autocreate.group.name.1: etc:webServiceClientUsers
2009-02-14 21:28:04,952: [main] WARN
GrouperCheckConfig.checkGroup(149) - auto-created
grouper.properties key configuration.autocreate.group.name.1:
etc:webServiceClientUsers
2009-02-14 21:28:05,015: [main] WARN
GrouperCheckConfig.checkGroups(469) - auto-added subject
mchyzer to group: etc:webServiceClientUsers
7/17/2015
University of Pennsylvania
123
GrouperWeb
WebServices
Services
Grouper
Authorization – actAs proxy
Sometimes you need run as a different user than logged in as
E.g. to run things as the “system” [root] user
Or if there is an app users are using, and you call the web
service as that user
Or if an admin user needs to proxy another user in the office
(maybe someone on vacation)
All calls have an optional actAs input
<WsRestAddMemberRequest>
<actAsSubjectLookup>
<subjectId>GrouperSystem</subjectId>
</actAsSubjectLookup>
</WsRestAddMemberRequest>
7/17/2015
University of Pennsylvania
124
GrouperWeb
WebServices
Services
Grouper
Authorization – actAs proxy (continued)
Any user can actAs themselves (why? Due to examples )
GrouperSystem [root] can act as anyone
You can configure groups of users who can actAs anyone
(in grouper-ws.properties)
ws.act.as.group = etc:webServiceActAsGroup
Or you can specify groups who can act as users in another
group (to clamp down a bit)
ws.act.as.group = orgs:admins123 :::: orgs:users123
In this case users in orgs:admins123 group can only actAs
any user in orgs:users123
7/17/2015
University of Pennsylvania
125
GrouperWeb
WebServices
Services
Grouper
Authorization – actAs proxy (continued)
Important to audit both the
logged in user and actAs user
7/17/2015
University of Pennsylvania
126
GrouperWeb
WebServices
Services
Grouper
Authorization – two factor (TODO)
Factor 1: What you know (password)
Factor 2: Where you are (assumes SSL)
7/17/2015
University of Pennsylvania
127
GrouperWeb
WebServices
Services
Grouper
BONUS MATERIAL:
DEVELOPMENT
ENVIRONMENTS
7/17/2015
University of Pennsylvania
128
GrouperWeb
WebServices
Services
Grouper
TCP/IP monitor
Need to have a way to see HTTP traffic to/from web service
Network level proxy works in non-SSL only
Axis has a swing tcp monitor
Ethereal
Axis has log settings to log the traffic from client (not server?)
Eclipse has built-in TCP/IP monitor (my choice)
Note: this has more uses than just web services
See video (make sure you have the Xvid codec):
https://wiki.internet2.edu/confluence/download/attachments/3
014660/eclipseTcp.avi
7/17/2015
University of Pennsylvania
129
GrouperWeb
WebServices
Services
Grouper
BONUS MATERIAL: JAVADOC
IN CVS
7/17/2015
University of Pennsylvania
130
GrouperWeb
WebServices
Services
Grouper
Javadoc in CVS
Ant script to make javadoc CVSweb ready
7/17/2015
University of Pennsylvania
131
GrouperWeb
WebServices
Services
Grouper
Javadoc in CVS (continued)
7/17/2015
University of Pennsylvania
132
GrouperWeb
WebServices
Services
Grouper
Javadoc in CVS (continued)
7/17/2015
University of Pennsylvania
133
GrouperWeb
WebServices
Services
Grouper
BONUS MATERIALS:
WEB SERVICE TESTING
7/17/2015
University of Pennsylvania
134
GrouperWeb
WebServices
Services
Grouper
Testing
There are lots of places to test web services
Best place is at the client
See movie (make sure you have the Xvid codec):
https://wiki.internet2.edu/confluence/download/attachments/3
014660/testing.avi
Most bugs found in Grouper web services could have been
avoided with more testing
Web services are easier to automatically test than web
applications
7/17/2015
University of Pennsylvania
135