-
Notifications
You must be signed in to change notification settings - Fork 370
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add application level authorization.
Enables better support for clients using an anonymous DTLS handshake and authorize the request then on the application level, e.g. username/password or tokens. In combination with proxies, this enables the "offload" the authentication from dtls and move it into the REST API. Signed-off-by: Achim Kraus <[email protected]>
- Loading branch information
Showing
18 changed files
with
1,288 additions
and
174 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
116 changes: 116 additions & 0 deletions
116
...in/java/org/eclipse/californium/elements/PrincipalAndAnonymousEndpointContextMatcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/******************************************************************************** | ||
* Copyright (c) 2025 Contributors to the Eclipse Foundation | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information regarding copyright ownership. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* https://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License | ||
* v1.0 which is available at | ||
* https://www.eclipse.org/org/documents/edl-v10.php. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause | ||
********************************************************************************/ | ||
package org.eclipse.californium.elements; | ||
|
||
import java.security.Principal; | ||
|
||
import org.eclipse.californium.elements.auth.ApplicationPrincipal; | ||
import org.eclipse.californium.elements.util.Bytes; | ||
|
||
/** | ||
* Principal based endpoint context matcher. | ||
* <p> | ||
* Matches DTLS based on the used principal or the session ID, if the principal | ||
* is anonymous. Requires unique and stable credentials. | ||
* | ||
* @since 4.0 | ||
*/ | ||
public class PrincipalAndAnonymousEndpointContextMatcher implements EndpointContextMatcher { | ||
|
||
public PrincipalAndAnonymousEndpointContextMatcher() { | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return "principal and anonymous correlation"; | ||
} | ||
|
||
/** | ||
* Gets identity from endpoint context. | ||
* <p> | ||
* Use the {@link Principal} if available and not | ||
* {@link ApplicationPrincipal#ANONYMOUS}. Otherwise use the DTLS session | ||
* ID. | ||
* | ||
* @param context endpoint context | ||
* @return identity, or {@code null}, if none is available. | ||
*/ | ||
private Object getIdentity(EndpointContext context) { | ||
Principal identity = context.getPeerIdentity(); | ||
if (identity != null && !identity.equals(ApplicationPrincipal.ANONYMOUS)) { | ||
return identity; | ||
} | ||
Bytes id = context.get(DtlsEndpointContext.KEY_SESSION_ID); | ||
if (id != null && !id.isEmpty()) { | ||
return id; | ||
} | ||
return null; | ||
} | ||
|
||
@Override | ||
public Object getEndpointIdentity(EndpointContext context) { | ||
Object identity = getIdentity(context); | ||
if (identity == null) { | ||
throw new IllegalArgumentException( | ||
"Principal identity and session id are missing in provided endpoint context!"); | ||
} | ||
return identity; | ||
} | ||
|
||
@Override | ||
public boolean isResponseRelatedToRequest(EndpointContext requestContext, EndpointContext responseContext) { | ||
return internalMatch(requestContext, responseContext); | ||
} | ||
|
||
@Override | ||
public boolean isToBeSent(EndpointContext messageContext, EndpointContext connectorContext) { | ||
if (null == connectorContext) { | ||
return true; | ||
} | ||
return internalMatch(messageContext, connectorContext); | ||
} | ||
|
||
private final boolean internalMatch(EndpointContext requestedContext, EndpointContext availableContext) { | ||
|
||
Object identity = getIdentity(requestedContext); | ||
if (identity != null) { | ||
return identity.equals(getIdentity(availableContext)); | ||
} | ||
String cipher = requestedContext.getString(DtlsEndpointContext.KEY_CIPHER); | ||
if (cipher != null) { | ||
if (!cipher.equals(availableContext.getString(DtlsEndpointContext.KEY_CIPHER))) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
@Override | ||
public String toRelevantState(EndpointContext context) { | ||
if (context == null) { | ||
return "n.a."; | ||
} else { | ||
StringBuilder builder = new StringBuilder(); | ||
builder.append("["); | ||
builder.append(getIdentity(context)); | ||
String cipher = context.getString(DtlsEndpointContext.KEY_CIPHER); | ||
if (cipher != null) { | ||
builder.append(",").append(cipher); | ||
} | ||
builder.append("]"); | ||
return builder.toString(); | ||
} | ||
} | ||
} |
57 changes: 57 additions & 0 deletions
57
...-connector/src/main/java/org/eclipse/californium/elements/auth/ApplicationAuthorizer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/******************************************************************************** | ||
* Copyright (c) 2025 Contributors to the Eclipse Foundation | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information regarding copyright ownership. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* https://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License | ||
* v1.0 which is available at | ||
* https://www.eclipse.org/org/documents/edl-v10.php. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause | ||
********************************************************************************/ | ||
package org.eclipse.californium.elements.auth; | ||
|
||
import java.security.Principal; | ||
import java.util.concurrent.Future; | ||
|
||
import org.eclipse.californium.elements.EndpointContext; | ||
|
||
/** | ||
* Application authorize. | ||
* <p> | ||
* Sets {@link Principal} from application layers. Used with | ||
* {@code DtlsConfig.DTLS_APPLICATION_AUTHORIZATION} to authorize or reject | ||
* anonymous clients. | ||
* | ||
* @since 4.0 | ||
*/ | ||
public interface ApplicationAuthorizer { | ||
|
||
/** | ||
* Authorize the associated connection with the {@link ApplicationPrincipal} | ||
* to prevent connection from being removed after in short time. | ||
* <p> | ||
* The Authorization may be processed asynchronous. A future request | ||
* therefore may still not contain the provided principal! Only if the | ||
* connection has not already a principal assigned, the provided one will be | ||
* assigned. | ||
* | ||
* @param context endpoint context | ||
* @param principal anonymous principal | ||
* @return future with boolean result. Completes with {@code true}, if the | ||
* principal was assigned, {@code false}, otherwise. | ||
*/ | ||
Future<Boolean> authorize(EndpointContext context, ApplicationPrincipal principal); | ||
|
||
/** | ||
* Reject authorization. | ||
* | ||
* @param context endpoint context to reject authorization. | ||
* @return future completes with removing the connection. | ||
*/ | ||
Future<Void> rejectAuthorization(EndpointContext context); | ||
|
||
} |
89 changes: 89 additions & 0 deletions
89
...t-connector/src/main/java/org/eclipse/californium/elements/auth/ApplicationPrincipal.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/******************************************************************************** | ||
* Copyright (c) 2025 Contributors to the Eclipse Foundation | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information regarding copyright ownership. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* https://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License | ||
* v1.0 which is available at | ||
* https://www.eclipse.org/org/documents/edl-v10.php. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause | ||
********************************************************************************/ | ||
package org.eclipse.californium.elements.auth; | ||
|
||
import java.util.Objects; | ||
|
||
/** | ||
* Application level principal. | ||
* | ||
* @since 4.0 | ||
*/ | ||
public class ApplicationPrincipal extends AbstractExtensiblePrincipal<ApplicationPrincipal> { | ||
|
||
/** | ||
* Anonymous principal. | ||
*/ | ||
public static final ApplicationPrincipal ANONYMOUS = new ApplicationPrincipal("anonymous"); | ||
|
||
/** | ||
* Principal's name. | ||
*/ | ||
private final String name; | ||
|
||
/** | ||
* Creates an application principal. | ||
* | ||
* @param name name | ||
*/ | ||
public ApplicationPrincipal(String name) { | ||
this.name = name; | ||
} | ||
|
||
/** | ||
* Creates an application principal. | ||
* | ||
* @param name name | ||
* @param additionalInformation additional information | ||
*/ | ||
private ApplicationPrincipal(String name, AdditionalInfo additionalInformation) { | ||
super(additionalInformation); | ||
this.name = name; | ||
} | ||
|
||
@Override | ||
public ApplicationPrincipal amend(AdditionalInfo additionalInfo) { | ||
return new ApplicationPrincipal(name, additionalInfo); | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return name; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Application Prinicpal [" + name + "]"; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return name.hashCode(); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (this == obj) { | ||
return true; | ||
} else if (obj == null) { | ||
return false; | ||
} else if (getClass() != obj.getClass()) { | ||
return false; | ||
} | ||
ApplicationPrincipal other = (ApplicationPrincipal) obj; | ||
return Objects.equals(name, other.name); | ||
} | ||
|
||
} |
Oops, something went wrong.