1
18
19 package io.undertow.security.impl;
20
21 import io.undertow.UndertowMessages;
22 import io.undertow.security.api.AuthenticationMechanism;
23 import io.undertow.security.api.AuthenticationMechanismFactory;
24 import io.undertow.security.api.SecurityContext;
25 import io.undertow.security.idm.Account;
26 import io.undertow.security.idm.IdentityManager;
27 import io.undertow.security.idm.PasswordCredential;
28 import io.undertow.server.HttpServerExchange;
29 import io.undertow.server.handlers.Cookie;
30 import io.undertow.server.handlers.form.FormParserFactory;
31 import io.undertow.util.HttpString;
32
33 import java.util.ArrayList;
34 import java.util.List;
35 import java.util.Map;
36
37 import static io.undertow.security.api.AuthenticationMechanism.AuthenticationMechanismOutcome.AUTHENTICATED;
38 import static io.undertow.security.api.AuthenticationMechanism.AuthenticationMechanismOutcome.NOT_ATTEMPTED;
39 import static io.undertow.security.api.AuthenticationMechanism.AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
40
41
47 public class GenericHeaderAuthenticationMechanism implements AuthenticationMechanism {
48
49 public static final AuthenticationMechanismFactory FACTORY = new Factory();
50
51 public static final String NAME = "GENERIC_HEADER";
52 public static final String IDENTITY_HEADER = "identity-header";
53 public static final String SESSION_HEADER = "session-header";
54
55 private final String mechanismName;
56 private final List<HttpString> identityHeaders;
57 private final List<String> sessionCookieNames;
58 private final IdentityManager identityManager;
59
60 public GenericHeaderAuthenticationMechanism(String mechanismName, List<HttpString> identityHeaders, List<String> sessionCookieNames, IdentityManager identityManager) {
61 this.mechanismName = mechanismName;
62 this.identityHeaders = identityHeaders;
63 this.sessionCookieNames = sessionCookieNames;
64 this.identityManager = identityManager;
65 }
66
67 @Override
68 public AuthenticationMechanismOutcome authenticate(HttpServerExchange exchange, SecurityContext securityContext) {
69 String principal = getPrincipal(exchange);
70 if(principal == null) {
71 return NOT_ATTEMPTED;
72 }
73 String session = getSession(exchange);
74 if(session == null) {
75 return NOT_ATTEMPTED;
76 }
77 Account account = identityManager.verify(principal, new PasswordCredential(session.toCharArray()));
78 if(account == null) {
79 securityContext.authenticationFailed(UndertowMessages.MESSAGES.authenticationFailed(principal), mechanismName);
80 return NOT_AUTHENTICATED;
81 }
82 securityContext.authenticationComplete(account, mechanismName, false);
83 return AUTHENTICATED;
84 }
85
86 private String getSession(HttpServerExchange exchange) {
87 for(String header : sessionCookieNames) {
88 Cookie cookie = exchange.getRequestCookies().get(header);
89 if(cookie != null) {
90 return cookie.getValue();
91 }
92 }
93 return null;
94 }
95
96 private String getPrincipal(HttpServerExchange exchange) {
97 for(HttpString header : identityHeaders) {
98 String res = exchange.getRequestHeaders().getFirst(header);
99 if(res != null) {
100 return res;
101 }
102 }
103 return null;
104 }
105
106 @Override
107 public ChallengeResult sendChallenge(HttpServerExchange exchange, SecurityContext securityContext) {
108 return ChallengeResult.NOT_SENT;
109 }
110
111
112 public static class Factory implements AuthenticationMechanismFactory {
113
114 @Deprecated
115 public Factory(IdentityManager identityManager) {
116 }
117
118 public Factory() {
119
120 }
121
122 @Override
123 public AuthenticationMechanism create(String mechanismName, IdentityManager identityManager, FormParserFactory formParserFactory, Map<String, String> properties) {
124 String identity = properties.get(IDENTITY_HEADER);
125 if(identity == null) {
126 throw UndertowMessages.MESSAGES.authenticationPropertyNotSet(mechanismName, IDENTITY_HEADER);
127 }
128 String session = properties.get(SESSION_HEADER);
129 if(session == null) {
130 throw UndertowMessages.MESSAGES.authenticationPropertyNotSet(mechanismName, SESSION_HEADER);
131 }
132 List<HttpString> ids = new ArrayList<>();
133 for(String s : identity.split(",")) {
134 ids.add(new HttpString(s));
135 }
136 List<String> sessions = new ArrayList<>();
137 for(String s : session.split(",")) {
138 sessions.add(s);
139 }
140 return new GenericHeaderAuthenticationMechanism(mechanismName, ids, sessions, identityManager);
141 }
142 }
143 }
144