Browse Source

re-implemented first part: authorization

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
sqlite
Stephan Richter 4 months ago
parent
commit
5c7f86c4a4
  1. 7
      de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/Constants.java
  2. 35
      de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/ClientController.java
  3. 6
      de.srsoftware.oidc.web/src/main/resources/de/clients.html
  4. 1
      de.srsoftware.oidc.web/src/main/resources/de/navigation.html
  5. 6
      de.srsoftware.oidc.web/src/main/resources/en/authorization.html
  6. 6
      de.srsoftware.oidc.web/src/main/resources/en/clients.html
  7. 6
      de.srsoftware.oidc.web/src/main/resources/en/edit_client.html
  8. 4
      de.srsoftware.oidc.web/src/main/resources/en/index.html
  9. 4
      de.srsoftware.oidc.web/src/main/resources/en/login.html
  10. 4
      de.srsoftware.oidc.web/src/main/resources/en/logout.html
  11. 1
      de.srsoftware.oidc.web/src/main/resources/en/navigation.html
  12. 6
      de.srsoftware.oidc.web/src/main/resources/en/new_client.html
  13. 13
      de.srsoftware.oidc.web/src/main/resources/en/scripts/authorization.js
  14. 0
      de.srsoftware.oidc.web/src/main/resources/en/scripts/clients.js
  15. 0
      de.srsoftware.oidc.web/src/main/resources/en/scripts/common.js
  16. 0
      de.srsoftware.oidc.web/src/main/resources/en/scripts/edit_client.js
  17. 0
      de.srsoftware.oidc.web/src/main/resources/en/scripts/login.js
  18. 0
      de.srsoftware.oidc.web/src/main/resources/en/scripts/logout.js
  19. 0
      de.srsoftware.oidc.web/src/main/resources/en/scripts/new_client.js
  20. 0
      de.srsoftware.oidc.web/src/main/resources/en/scripts/settings.js
  21. 0
      de.srsoftware.oidc.web/src/main/resources/en/scripts/user.js
  22. 6
      de.srsoftware.oidc.web/src/main/resources/en/settings.html

7
de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/Constants.java

@ -12,18 +12,25 @@ public class Constants {
public static final String CLIENT_ID = "client_id"; public static final String CLIENT_ID = "client_id";
public static final String CLIENT_SECRET = "client_secret"; public static final String CLIENT_SECRET = "client_secret";
public static final String CODE = "code"; public static final String CODE = "code";
public static final String ERROR = "error";
public static final String CONFIG_PATH = "LIGHTOIDC_CONFIG_PATH"; public static final String CONFIG_PATH = "LIGHTOIDC_CONFIG_PATH";
public static final String CONFIRMED = "confirmed"; public static final String CONFIRMED = "confirmed";
public static final String DAYS = "days"; public static final String DAYS = "days";
public static final String ERROR_DESCRIPTION = "error_description";
public static final String EXPIRATION = "expiration"; public static final String EXPIRATION = "expiration";
public static final String EXPIRES_IN = "expires_in"; public static final String EXPIRES_IN = "expires_in";
public static final String GRANT_TYPE = "grant_type"; public static final String GRANT_TYPE = "grant_type";
public static final String ID_TOKEN = "id_token"; public static final String ID_TOKEN = "id_token";
public static final String INVALID_REDIRECT_URI = "invalid_request_uri";
public static final String INVALID_REQUEST = "invalid_request";
public static final String INVALID_REQUEST_OBJECT = "invalid_request_object";
public static final String INVALID_SCOPE = "invalid_scope";
public static final String NAME = "name"; public static final String NAME = "name";
public static final String NONCE = "nonce"; public static final String NONCE = "nonce";
public static final String OPENID = "openid"; public static final String OPENID = "openid";
public static final String REDIRECT_URI = "redirect_uri"; public static final String REDIRECT_URI = "redirect_uri";
public static final String REDIRECT_URIS = "redirect_uris"; public static final String REDIRECT_URIS = "redirect_uris";
public static final String REQUEST_NOT_SUPPORTED = "request_not_supported";
public static final String RESPONSE_TYPE = "response_type"; public static final String RESPONSE_TYPE = "response_type";
public static final String SCOPE = "scope"; public static final String SCOPE = "scope";
public static final String SECRET = "secret"; public static final String SECRET = "secret";

35
de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/ClientController.java

@ -25,36 +25,45 @@ public class ClientController extends Controller {
clients = clientService; clients = clientService;
} }
private boolean authorizationError(HttpExchange ex, String errorCode, String description, String state) throws IOException {
var map = new HashMap<String, String>();
map.put(ERROR,errorCode);
if (description != null) map.put(ERROR_DESCRIPTION,description);
if (state != null) map.put(STATE,state);
return badRequest(ex,map);
}
private boolean authorize(HttpExchange ex, Session session) throws IOException { private boolean authorize(HttpExchange ex, Session session) throws IOException {
var user = session.user(); var user = session.user();
var json = json(ex); var json = json(ex);
for (String param : List.of(SCOPE, RESPONSE_TYPE, CLIENT_ID, REDIRECT_URI)) { var state = json.has(STATE) ? json.getString(STATE) : null;
if (!json.has(param)) return badRequest(ex, "Missing required parameter \"%s\"!".formatted(param)); if (!json.has(CLIENT_ID)) return authorizationError(ex, INVALID_REQUEST,"Missing required parameter \"%s\"!".formatted(CLIENT_ID),state);
var clientId = json.getString(CLIENT_ID);
var optClient = clients.getClient(clientId);
if (optClient.isEmpty()) return authorizationError(ex,INVALID_REQUEST_OBJECT,"unknown client: %s".formatted(clientId),state);
for (String param : List.of(SCOPE, RESPONSE_TYPE, REDIRECT_URI)) {
if (!json.has(param)) return authorizationError(ex,INVALID_REQUEST,"Missing required parameter \"%s\"!".formatted(param),state);
} }
var scopes = toList(json, SCOPE); var scopes = toList(json, SCOPE);
if (!scopes.contains(OPENID)) return badRequest(ex, "This is an OpenID Provider. You should request \"openid\" scope!"); if (!scopes.contains(OPENID)) return authorizationError(ex,INVALID_SCOPE,"This is an OpenID Provider. You should request \"openid\" scope!",state);
var responseTypes = toList(json, RESPONSE_TYPE); var responseTypes = toList(json, RESPONSE_TYPE);
for (var responseType : responseTypes) { for (var responseType : responseTypes) {
switch (responseType) { switch (responseType) {
case ID_TOKEN: case ID_TOKEN:
case TOKEN: case TOKEN:
return sendContent(ex, HTTP_NOT_IMPLEMENTED, "Response type \"%s\" currently not supported".formatted(responseType)); return authorizationError(ex, REQUEST_NOT_SUPPORTED, "Response type \"%s\" currently not supported".formatted(responseType),state);
case CODE: case CODE:
break; break;
default: default:
return badRequest(ex, "Unknown response type \"%s\"".formatted(responseType)); return authorizationError(ex,INVALID_REQUEST_OBJECT,"Unknown response type \"%s\"".formatted(responseType),state);
} }
} }
if (!responseTypes.contains(CODE)) return badRequest(ex, "Sorry, at the moment I can only handle \"%s\" response type".formatted(CODE)); if ( !responseTypes.contains(CODE)) return authorizationError(ex, REQUEST_NOT_SUPPORTED, "Sorry, at the moment I can only handle \"%s\" response type".formatted(CODE),state);
var clientId = json.getString(CLIENT_ID);
var optClient = clients.getClient(clientId);
if (optClient.isEmpty()) return badRequest(ex, Map.of(CAUSE, "unknown client", CLIENT_ID, clientId));
var client = optClient.get(); var client = optClient.get();
var redirect = json.getString(REDIRECT_URI); var redirect = json.getString(REDIRECT_URI);
if (!client.redirectUris().contains(redirect)) return badRequest(ex, Map.of(CAUSE, "unknown redirect uri", REDIRECT_URI, redirect)); if (!client.redirectUris().contains(redirect)) authorizationError(ex, INVALID_REDIRECT_URI, "unknown redirect uri: %s".formatted(redirect),state);
var state = json.has(STATE) ? json.getString(STATE) : null;
client.nonce(json.has(NONCE) ? json.getString(NONCE) : null); client.nonce(json.has(NONCE) ? json.getString(NONCE) : null);
if (json.has(AUTHORZED)) { if (json.has(AUTHORZED)) {
@ -69,9 +78,9 @@ public class ClientController extends Controller {
if (!authResult.unauthorizedScopes().isEmpty()) { if (!authResult.unauthorizedScopes().isEmpty()) {
return sendContent(ex, Map.of("unauthorized_scopes", authResult.unauthorizedScopes(), "rp", client.name())); return sendContent(ex, Map.of("unauthorized_scopes", authResult.unauthorizedScopes(), "rp", client.name()));
} }
var authoriedScopes = authResult.authorizedScopes().stream().map(AuthorizedScope::scope).collect(Collectors.joining(" ")); var authorizedScopes = authResult.authorizedScopes().stream().map(AuthorizedScope::scope).collect(Collectors.joining(" "));
var result = new HashMap<String, String>(); var result = new HashMap<String, String>();
result.put(SCOPE, authoriedScopes); result.put(SCOPE, authorizedScopes);
result.put(CODE, authResult.authCode()); result.put(CODE, authResult.authCode());
if (state != null) result.put(STATE, state); if (state != null) result.put(STATE, state);
return sendContent(ex, result); return sendContent(ex, result);

6
de.srsoftware.oidc.web/src/main/resources/de/clients.html

@ -2,9 +2,9 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Light OIDC</title> <title>Light OIDC</title>
<script src="common.js"></script> <script src="scripts/common.js"></script>
<script src="user.js"></script> <script src="scripts/user.js"></script>
<script src="clients.js"></script> <script src="scripts/clients.js"></script>
<link rel="stylesheet" href="style.css" /> <link rel="stylesheet" href="style.css" />
</head> </head>
<body> <body>

1
de.srsoftware.oidc.web/src/main/resources/de/navigation.html

@ -1,5 +1,6 @@
<a href="index.html">Übersicht</a> <a href="index.html">Übersicht</a>
<a href="clients.html" class="MANAGE_CLIENTS">Clients</a> <a href="clients.html" class="MANAGE_CLIENTS">Clients</a>
<a href="users.html" class="MANAGE_USERS">Benutzer</a> <a href="users.html" class="MANAGE_USERS">Benutzer</a>
<a href="https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth" target="_blank">Spec</a>
<a href="settings.html">Einstellungen</a> <a href="settings.html">Einstellungen</a>
<a href="logout.html">Ausloggen</a> <a href="logout.html">Ausloggen</a>

6
de.srsoftware.oidc.web/src/main/resources/en/authorization.html

@ -2,9 +2,9 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Light OIDC</title> <title>Light OIDC</title>
<script src="common.js"></script> <script src="scripts/common.js"></script>
<script src="user.js"></script> <script src="scripts/user.js"></script>
<script src="authorization.js"></script> <script src="scripts/authorization.js"></script>
<link rel="stylesheet" href="style.css" /> <link rel="stylesheet" href="style.css" />
</head> </head>
<body> <body>

6
de.srsoftware.oidc.web/src/main/resources/en/clients.html

@ -2,9 +2,9 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Light OIDC</title> <title>Light OIDC</title>
<script src="common.js"></script> <script src="scripts/common.js"></script>
<script src="user.js"></script> <script src="scripts/user.js"></script>
<script src="clients.js"></script> <script src="scripts/clients.js"></script>
<link rel="stylesheet" href="style.css" /> <link rel="stylesheet" href="style.css" />
</head> </head>
<body> <body>

6
de.srsoftware.oidc.web/src/main/resources/en/edit_client.html

@ -2,9 +2,9 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Light OIDC</title> <title>Light OIDC</title>
<script src="common.js"></script> <script src="scripts/common.js"></script>
<script src="user.js"></script> <script src="scripts/user.js"></script>
<script src="edit_client.js"></script> <script src="scripts/edit_client.js"></script>
<link rel="stylesheet" href="style.css" /> <link rel="stylesheet" href="style.css" />
</head> </head>
<body> <body>

4
de.srsoftware.oidc.web/src/main/resources/en/index.html

@ -2,8 +2,8 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Light OIDC</title> <title>Light OIDC</title>
<script src="common.js"></script> <script src="scripts/common.js"></script>
<script src="user.js"></script> <script src="scripts/user.js"></script>
<link rel="stylesheet" href="style.css" /> <link rel="stylesheet" href="style.css" />
</head> </head>
<body> <body>

4
de.srsoftware.oidc.web/src/main/resources/en/login.html

@ -2,8 +2,8 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Light OIDC</title> <title>Light OIDC</title>
<script src="common.js"></script> <script src="scripts/common.js"></script>
<script src="login.js"></script> <script src="scripts/login.js"></script>
<link rel="stylesheet" href="style.css" /> <link rel="stylesheet" href="style.css" />
</head> </head>
<body> <body>

4
de.srsoftware.oidc.web/src/main/resources/en/logout.html

@ -2,8 +2,8 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Light OIDC</title> <title>Light OIDC</title>
<script src="common.js"></script> <script src="scripts/common.js"></script>
<script src="logout.js"></script> <script src="scripts/logout.js"></script>
<link rel="stylesheet" href="style.css" /> <link rel="stylesheet" href="style.css" />
</head> </head>
<body> <body>

1
de.srsoftware.oidc.web/src/main/resources/en/navigation.html

@ -1,5 +1,6 @@
<a href="index.html">Dashboard</a> <a href="index.html">Dashboard</a>
<a href="clients.html" class="MANAGE_CLIENTS">Clients</a> <a href="clients.html" class="MANAGE_CLIENTS">Clients</a>
<a href="users.html" class="MANAGE_USERS">Users</a> <a href="users.html" class="MANAGE_USERS">Users</a>
<a href="https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth" target="_blank">Spec</a>
<a href="settings.html">Settings</a> <a href="settings.html">Settings</a>
<a href="logout.html">Logout</a> <a href="logout.html">Logout</a>

6
de.srsoftware.oidc.web/src/main/resources/en/new_client.html

@ -2,9 +2,9 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Light OIDC</title> <title>Light OIDC</title>
<script src="common.js"></script> <script src="scripts/common.js"></script>
<script src="user.js"></script> <script src="scripts/user.js"></script>
<script src="new_client.js"></script> <script src="scripts/new_client.js"></script>
<link rel="stylesheet" href="style.css" /> <link rel="stylesheet" href="style.css" />
</head> </head>
<body> <body>

13
de.srsoftware.oidc.web/src/main/resources/en/authorization.js → de.srsoftware.oidc.web/src/main/resources/en/scripts/authorization.js

@ -39,14 +39,19 @@ async function handleResponse(response){
} }
show('missing_scopes'); show('missing_scopes');
} else { } else {
console.log(response); console.log("handleResponse(…) ← ",response);
if (response.status == 401){ if (response.status == 401){
login(); login();
return; return;
} }
var text = await response.text(); var json = await response.json();
setText('error',"Error: <br/>"+text); setText('error',"Error: <br/>"+json.error_description);
show('error'); show('error');
if (json.error != "invalid_request_uri"){
var url = params.get('redirect_uri') + '?' + new URLSearchParams(json).toString();
console.log('redirecting to '+url);
redirect(url);
}
} }
} }
@ -56,7 +61,7 @@ function grantAutorization(days){
} }
function denyAutorization(){ function denyAutorization(){
redirect(params.get('redirect_uri')+"?error=access denied"); redirect(params.get('redirect_uri')+"?error=consent_required");
} }
function backendAutorization(){ function backendAutorization(){

0
de.srsoftware.oidc.web/src/main/resources/en/clients.js → de.srsoftware.oidc.web/src/main/resources/en/scripts/clients.js

0
de.srsoftware.oidc.web/src/main/resources/en/common.js → de.srsoftware.oidc.web/src/main/resources/en/scripts/common.js

0
de.srsoftware.oidc.web/src/main/resources/en/edit_client.js → de.srsoftware.oidc.web/src/main/resources/en/scripts/edit_client.js

0
de.srsoftware.oidc.web/src/main/resources/en/login.js → de.srsoftware.oidc.web/src/main/resources/en/scripts/login.js

0
de.srsoftware.oidc.web/src/main/resources/en/logout.js → de.srsoftware.oidc.web/src/main/resources/en/scripts/logout.js

0
de.srsoftware.oidc.web/src/main/resources/en/new_client.js → de.srsoftware.oidc.web/src/main/resources/en/scripts/new_client.js

0
de.srsoftware.oidc.web/src/main/resources/en/settings.js → de.srsoftware.oidc.web/src/main/resources/en/scripts/settings.js

0
de.srsoftware.oidc.web/src/main/resources/en/user.js → de.srsoftware.oidc.web/src/main/resources/en/scripts/user.js

6
de.srsoftware.oidc.web/src/main/resources/en/settings.html

@ -2,9 +2,9 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Light OIDC</title> <title>Light OIDC</title>
<script src="common.js"></script> <script src="scripts/common.js"></script>
<script src="user.js"></script> <script src="scripts/user.js"></script>
<script src="settings.js"></script> <script src="scripts/settings.js"></script>
<link rel="stylesheet" href="style.css" /> <link rel="stylesheet" href="style.css" />
</head> </head>
<body> <body>

Loading…
Cancel
Save