Site doc updates
This commit is contained in:
parent
be865b0539
commit
fcf0604e98
|
@ -2,33 +2,89 @@ package example;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.method.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.auth.AuthorizationInterceptor;
|
||||
import ca.uhn.fhir.rest.server.interceptor.auth.IAuthRule;
|
||||
import ca.uhn.fhir.rest.server.interceptor.auth.RuleBuilder;
|
||||
|
||||
public class AuthorizationInterceptors {
|
||||
|
||||
public class PatientResourceProvider implements IResourceProvider
|
||||
{
|
||||
|
||||
@Override
|
||||
public Class<? extends IBaseResource> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
public MethodOutcome create(@ResourceParam Patient thePatient, RequestDetails theRequestDetails) {
|
||||
|
||||
return new MethodOutcome(); // populate this
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//START SNIPPET: patientAndAdmin
|
||||
public class PatientAndAdminAuthorizationInterceptor extends AuthorizationInterceptor {
|
||||
|
||||
@Override
|
||||
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
|
||||
|
||||
// Process authorization header - The following is a fake
|
||||
// implementation. Obviously we'd want something more real
|
||||
// for a production scenario.
|
||||
//
|
||||
// In this basic example we have two hardcoded bearer tokens,
|
||||
// one which is for a user that has access to one patient, and
|
||||
// another that has full access.
|
||||
IdDt userIdPatientId = null;
|
||||
boolean userIsAdmin = false;
|
||||
String authHeader = theRequestDetails.getHeader("Authorization");
|
||||
/*
|
||||
* Process authorization header - The following is a fake
|
||||
* implementation. Obviously we'd want something more real
|
||||
* for a production scenario.
|
||||
*/
|
||||
if ("Bearer dfw98h38r".equals(authHeader)) {
|
||||
// This user has access only to Patient/1 resources
|
||||
userIdPatientId = new IdDt("Patient", 1L);
|
||||
} else if ("Bearer 39ff939jgg".equals(authHeader)) {
|
||||
// This user has access to everything
|
||||
userIsAdmin = true;
|
||||
} else {
|
||||
// Throw an HTTP 401
|
||||
throw new AuthenticationException("Missing or invalid Authorization header value");
|
||||
}
|
||||
|
||||
// If the user is a specific patient, we create the following rule chain:
|
||||
// Allow the user to read anything in their own patient compartment
|
||||
// Allow the user to write anything in their own patient compartment
|
||||
// If a client request doesn't pass either of the above, deny it
|
||||
if (userIdPatientId != null) {
|
||||
return new RuleBuilder()
|
||||
.allow().read().allResources().inCompartment("Patient", userIdPatientId).andThen()
|
||||
.allow().write().allResources().inCompartment("Patient", userIdPatientId).andThen()
|
||||
.denyAll()
|
||||
.build();
|
||||
}
|
||||
|
||||
// If the authorization header was determined to be
|
||||
Long callerIsPatientId = null;
|
||||
// If the user is an admin, allow everything
|
||||
if (userIsAdmin) {
|
||||
return new RuleBuilder()
|
||||
.allowAll()
|
||||
.build();
|
||||
}
|
||||
|
||||
// By default, deny everything. This should never get hit, but it's
|
||||
// good to be defensive
|
||||
return new RuleBuilder()
|
||||
.deny("Rule 1").read().resourcesOfType(Patient.class).withAnyId().andThen()
|
||||
.allowAll("Default Rule")
|
||||
.denyAll()
|
||||
.build();
|
||||
}
|
||||
}
|
||||
//END SNIPPET: patientAndAdmin
|
||||
|
||||
}
|
||||
|
|
|
@ -49,6 +49,11 @@ import ca.uhn.fhir.util.CoverageIgnore;
|
|||
* This class is a base class for interceptors which can be used to
|
||||
* inspect requests and responses to determine whether the calling user
|
||||
* has permission to perform the given action.
|
||||
* <p>
|
||||
* See the HAPI FHIR
|
||||
* <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_server_security.html">Documentation on Server Security</a>
|
||||
* for information on how to use this interceptor.
|
||||
* </p>
|
||||
*/
|
||||
public class AuthorizationInterceptor extends InterceptorAdapter implements IServerOperationInterceptor, IRuleApplier {
|
||||
|
||||
|
|
|
@ -97,8 +97,9 @@
|
|||
<item name="Using RESTful Server" href="./doc_rest_server.html" />
|
||||
<item name="RESTful Operations" href="./doc_rest_operations.html" />
|
||||
<item name="Narrative Generator" href="./doc_narrative.html" />
|
||||
<item name="CORS Support" href="./doc_cors.html" />
|
||||
<item name="Interceptors (server)" href="./doc_rest_server_interceptor.html" />
|
||||
<item name="Security" href="./doc_rest_server_security.html" />
|
||||
<item name="CORS Support" href="./doc_cors.html" />
|
||||
<item name="Web Testing UI" href="./doc_server_tester.html" />
|
||||
<item name="JAX-RS Support" href="./doc_rest_server_jaxrs.html" />
|
||||
</item>
|
||||
|
|
|
@ -143,7 +143,7 @@ $ mvn install]]></source>
|
|||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://github.com/jamesagnew/hapi-fhir/blob/master/hapi-fhir-jpaserver-example/src/main/webapp/WEB-INF/hapi-fhir-server-database-config.xml"><b>hapi-fhir-server-database-config.xml</b></a>:
|
||||
<a href="https://github.com/jamesagnew/hapi-fhir/blob/master/hapi-fhir-jpaserver-example/src/main/java/ca/uhn/fhir/jpa/demo/FhirServerConfig.java"><b>FhirServerConfig.java</b></a>:
|
||||
Configures the database connection settings
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -81,7 +81,9 @@
|
|||
<p class="doc_info_bubble">
|
||||
AuthorizationInterceptor is a new feature in HAPI FHIR, and has not yet
|
||||
been heavily tested. Use with caution, and do lots of testing! We welcome
|
||||
feedback and suggestions on this feature.
|
||||
feedback and suggestions on this feature. In addition, this documentation is
|
||||
not yet complete. More examples and details will be added soon! Please get in
|
||||
touch if you'd like to help test, have suggestions, etc.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@ -96,6 +98,45 @@
|
|||
might be detemrined to belong to an administrator user, and
|
||||
could be declared to be allowed to do anything.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The AuthorizationInterceptor is used by subclassing it and then registering your
|
||||
subclass with the <code>RestfulServer</code>. The following example shows a subclassed
|
||||
interceptor implementing some basic rules:
|
||||
</p>
|
||||
|
||||
<macro name="snippet">
|
||||
<param name="id" value="patientAndAdmin" />
|
||||
<param name="file" value="examples/src/main/java/example/AuthorizationInterceptors.java" />
|
||||
</macro>
|
||||
|
||||
<subsection name="Using AuthorizationInterceptor in a REST Server">
|
||||
|
||||
<p>
|
||||
The AuthorizationInterceptor works by examining the client request
|
||||
in order to determine whether "write" operations are legal, and looks at
|
||||
the response from the server in order to determine whether "read" operations
|
||||
are legal.
|
||||
</p>
|
||||
<p>
|
||||
This approach has limitations however: If a request has a conditional operation,
|
||||
such as a delete operation which uses a search URL, or a create operation which
|
||||
uses an <code>If-None-Exist</code> header, the interceptor will not know the
|
||||
actual target until the server actually processes the request.
|
||||
</p>
|
||||
<p>
|
||||
For better security, individual resource providers should notify interceptors
|
||||
about their actual targets in the event of any "write" operations (create,
|
||||
operations embedded in transactions, etc.)
|
||||
</p>
|
||||
<p>
|
||||
The mechanism for doing this isn't yet fully documented, this will be improved
|
||||
over the next release cycle (post 1.5). Please get in touch on our google group
|
||||
if you want to help!
|
||||
</p>
|
||||
|
||||
</subsection>
|
||||
|
||||
</section>
|
||||
|
||||
</body>
|
||||
|
|
|
@ -44,8 +44,9 @@
|
|||
<li><a href="./doc_rest_server.html">Using RESTful Server</a></li>
|
||||
<li><a href="./doc_rest_operations.html">RESTful Operations</a></li>
|
||||
<li><a href="./doc_narrative.html">Narrative Generator</a></li>
|
||||
<li><a href="./doc_cors.html">CORS Support</a></li>
|
||||
<li><a href="./doc_rest_server_interceptor.html">Interceptors (server)</a></li>
|
||||
<li><a href="./doc_rest_server_security.html">Security</a></li>
|
||||
<li><a href="./doc_cors.html">CORS Support</a></li>
|
||||
<li><a href="./doc_server_tester.html">Web Testing UI</a></li>
|
||||
<li><a href="./doc_rest_server_jaxrs.html">JAX-RS Support</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -93,6 +93,12 @@
|
|||
<a href="./doc_rest_server_security.html">Server Security Interceptor</a>
|
||||
has been added.
|
||||
</li>
|
||||
<li>
|
||||
The JPA server has been enhanced so that search results are now paged into
|
||||
the database instead of simply to memory. This makes the server much more
|
||||
scalable to supporting larger result sets, larger volumes of queries, and
|
||||
operation across multiple nodes in a cluster.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
- <a href="https://github.com/jamesagnew/">James Agnew</a>
|
||||
|
|
Loading…
Reference in New Issue