mirror of
https://github.com/ysoftdevs/oauth-playground-server.git
synced 2026-03-18 07:14:24 +01:00
Client and user validation
This commit is contained in:
@@ -1,10 +1,19 @@
|
||||
package com.ysoft.geecon;
|
||||
|
||||
import com.ysoft.geecon.dto.OAuthClient;
|
||||
import com.ysoft.geecon.repo.ClientsRepo;
|
||||
import com.ysoft.geecon.repo.UsersRepo;
|
||||
import io.quarkus.qute.CheckedTemplate;
|
||||
import io.quarkus.qute.TemplateInstance;
|
||||
import io.quarkus.runtime.util.StringUtil;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.core.UriBuilder;
|
||||
import org.jboss.resteasy.reactive.RestQuery;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
@Path("/auth")
|
||||
@@ -13,26 +22,128 @@ public class OAuthResource {
|
||||
@CheckedTemplate
|
||||
public static class Templates {
|
||||
public static native TemplateInstance login(String loginHint, String error);
|
||||
|
||||
public static native TemplateInstance consents(List<String> scopes, String error);
|
||||
}
|
||||
|
||||
|
||||
@Inject
|
||||
ClientsRepo clientsRepo;
|
||||
@Inject
|
||||
UsersRepo usersRepo;
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.TEXT_HTML)
|
||||
public TemplateInstance get(@QueryParam("login_hint") String loginHint) {
|
||||
return Templates.login(loginHint, "");
|
||||
public TemplateInstance get(AuthParams params) {
|
||||
validateClient(params);
|
||||
|
||||
return Templates.login(params.loginHint, "");
|
||||
}
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.TEXT_HTML)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
public TemplateInstance post(@FormParam("username") String username,
|
||||
@FormParam("password") String password ) {
|
||||
if ("Password1".equals(password)) {
|
||||
return Templates.consents(List.of("scope1"), "");
|
||||
} else {
|
||||
public Object post(AuthParams params,
|
||||
@FormParam("username") String username,
|
||||
@FormParam("password") String password) {
|
||||
validateClient(params);
|
||||
var user = usersRepo.getUser(username);
|
||||
if (user.isEmpty()) {
|
||||
return Templates.login(username, "invalid_credentials");
|
||||
}
|
||||
if (!user.get().validatePassword(password)) {
|
||||
return Templates.login(username, "invalid_credentials");
|
||||
}
|
||||
|
||||
return Response.seeOther(UriBuilder.fromUri(params.redirectUri)
|
||||
.queryParam("code", "randomCode")
|
||||
.queryParam("state", params.state)
|
||||
.build())
|
||||
.build();
|
||||
}
|
||||
|
||||
private OAuthClient validateClient(AuthParams params) {
|
||||
var client = clientsRepo.getClient(params.clientId)
|
||||
.orElseThrow(() -> new RuntimeException("Not a valid client"));
|
||||
if (!client.validateRedirectUri(params.redirectUri)) {
|
||||
throw new RuntimeException("Invalid redirect URI");
|
||||
}
|
||||
if (StringUtil.isNullOrEmpty(params.state)) {
|
||||
throw new RuntimeException("Invalid state");
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
public static class AuthParams {
|
||||
public enum ResponseType {
|
||||
code
|
||||
}
|
||||
|
||||
@RestQuery("login_hint")
|
||||
String loginHint;
|
||||
@RestQuery("response_type")
|
||||
ResponseType responseType;
|
||||
@RestQuery("client_id")
|
||||
String clientId;
|
||||
@RestQuery("redirect_uri")
|
||||
String redirectUri;
|
||||
@RestQuery("scope")
|
||||
String scope;
|
||||
@RestQuery("state")
|
||||
String state;
|
||||
|
||||
public String getLoginHint() {
|
||||
return loginHint;
|
||||
}
|
||||
|
||||
public void setLoginHint(String loginHint) {
|
||||
this.loginHint = loginHint;
|
||||
}
|
||||
|
||||
public ResponseType getResponseType() {
|
||||
return responseType;
|
||||
}
|
||||
|
||||
public void setResponseType(ResponseType responseType) {
|
||||
this.responseType = responseType;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public String getRedirectUri() {
|
||||
return redirectUri;
|
||||
}
|
||||
|
||||
public void setRedirectUri(String redirectUri) {
|
||||
this.redirectUri = redirectUri;
|
||||
}
|
||||
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
public void setScope(String scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
7
src/main/java/com/ysoft/geecon/dto/OAuthClient.java
Normal file
7
src/main/java/com/ysoft/geecon/dto/OAuthClient.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package com.ysoft.geecon.dto;
|
||||
|
||||
public record OAuthClient(String clientId, String clientSecret, String redirectUri) {
|
||||
public boolean validateRedirectUri(String redirectUri) {
|
||||
return this.redirectUri != null && this.redirectUri.equals(redirectUri);
|
||||
}
|
||||
}
|
||||
7
src/main/java/com/ysoft/geecon/dto/User.java
Normal file
7
src/main/java/com/ysoft/geecon/dto/User.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package com.ysoft.geecon.dto;
|
||||
|
||||
public record User(String login, String password) {
|
||||
public boolean validatePassword(String password) {
|
||||
return this.password != null && this.password.equals(password);
|
||||
}
|
||||
}
|
||||
26
src/main/java/com/ysoft/geecon/repo/ClientsRepo.java
Normal file
26
src/main/java/com/ysoft/geecon/repo/ClientsRepo.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package com.ysoft.geecon.repo;
|
||||
|
||||
|
||||
import com.ysoft.geecon.dto.OAuthClient;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@ApplicationScoped
|
||||
public class ClientsRepo {
|
||||
private final Map<String, OAuthClient> clients = new HashMap<>();
|
||||
|
||||
public ClientsRepo() {
|
||||
register(new OAuthClient("my-public-client", null, "https://localhost:8888/oauth_success"));
|
||||
}
|
||||
|
||||
public Optional<OAuthClient> getClient(String clientId) {
|
||||
return Optional.ofNullable(clients.get(clientId));
|
||||
}
|
||||
|
||||
private void register(OAuthClient client) {
|
||||
clients.put(client.clientId(), client);
|
||||
}
|
||||
}
|
||||
26
src/main/java/com/ysoft/geecon/repo/UsersRepo.java
Normal file
26
src/main/java/com/ysoft/geecon/repo/UsersRepo.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package com.ysoft.geecon.repo;
|
||||
|
||||
import com.ysoft.geecon.dto.OAuthClient;
|
||||
import com.ysoft.geecon.dto.User;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@ApplicationScoped
|
||||
public class UsersRepo {
|
||||
private final Map<String, User> users = new HashMap<>();
|
||||
|
||||
public UsersRepo() {
|
||||
register(new User("bob", "Password1"));
|
||||
}
|
||||
|
||||
public Optional<User> getUser(String username) {
|
||||
return Optional.ofNullable(users.get(username));
|
||||
}
|
||||
|
||||
private void register(User user) {
|
||||
users.put(user.login(), user);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user