1
18 package io.undertow.security.impl;
19
20 import static io.undertow.UndertowMessages.MESSAGES;
21
22 import io.undertow.UndertowLogger;
23 import io.undertow.security.api.NotificationReceiver;
24 import io.undertow.security.api.SecurityContext;
25 import io.undertow.security.api.SecurityNotification;
26 import io.undertow.security.api.SecurityNotification.EventType;
27 import io.undertow.security.idm.Account;
28 import io.undertow.server.HttpServerExchange;
29
30
36 public abstract class AbstractSecurityContext implements SecurityContext {
37
38 private boolean authenticationRequired;
39 protected final HttpServerExchange exchange;
40
41 private Node<NotificationReceiver> notificationReceivers = null;
42
43 private Account account;
44 private String mechanismName;
45
46 protected AbstractSecurityContext(final HttpServerExchange exchange) {
47 this.exchange = exchange;
48 }
49
50 @Override
51 public void setAuthenticationRequired() {
52 authenticationRequired = true;
53 }
54
55 @Override
56 public boolean isAuthenticationRequired() {
57 return authenticationRequired;
58 }
59
60 @Override
61 public boolean isAuthenticated() {
62 return account != null;
63 }
64
65 @Override
66 public Account getAuthenticatedAccount() {
67 return account;
68 }
69
70
73 @Override
74 public String getMechanismName() {
75 return mechanismName;
76 }
77
78 @Override
79 public void authenticationComplete(Account account, String mechanism, final boolean cachingRequired) {
80 authenticationComplete(account, mechanism, false, cachingRequired);
81 }
82
83 protected void authenticationComplete(Account account, String mechanism, boolean programatic, final boolean cachingRequired) {
84 this.account = account;
85 this.mechanismName = mechanism;
86
87 UndertowLogger.SECURITY_LOGGER.debugf("Authenticated as %s, roles %s", account.getPrincipal().getName(), account.getRoles());
88 sendNoticiation(new SecurityNotification(exchange, EventType.AUTHENTICATED, account, mechanism, programatic,
89 MESSAGES.userAuthenticated(account.getPrincipal().getName()), cachingRequired));
90 }
91
92 @Override
93 public void authenticationFailed(String message, String mechanism) {
94 UndertowLogger.SECURITY_LOGGER.debugf("Authentication failed with message %s and mechanism %s for %s", message, mechanism, exchange);
95 sendNoticiation(new SecurityNotification(exchange, EventType.FAILED_AUTHENTICATION, null, mechanism, false, message, true));
96 }
97
98 @Override
99 public void registerNotificationReceiver(NotificationReceiver receiver) {
100 if(notificationReceivers == null) {
101 notificationReceivers = new Node<>(receiver);
102 } else {
103 Node<NotificationReceiver> cur = notificationReceivers;
104 while (cur.next != null) {
105 cur = cur.next;
106 }
107 cur.next = new Node<>(receiver);
108 }
109 }
110
111 @Override
112 public void removeNotificationReceiver(NotificationReceiver receiver) {
113 Node<NotificationReceiver> cur = notificationReceivers;
114 if(receiver.equals(cur.item)) {
115 notificationReceivers = cur.next;
116 } else {
117 Node<NotificationReceiver> old = cur;
118 while (cur.next != null) {
119 cur = cur.next;
120 if(receiver.equals(cur.item)) {
121 old.next = cur.next;
122 }
123 old = cur;
124 }
125 }
126 }
127
128 private void sendNoticiation(final SecurityNotification notification) {
129 Node<NotificationReceiver> cur = notificationReceivers;
130 while (cur != null) {
131 cur.item.handleNotification(notification);
132 cur = cur.next;
133 }
134 }
135
136 @Override
137 public void logout() {
138 if (!isAuthenticated()) {
139 return;
140 }
141 UndertowLogger.SECURITY_LOGGER.debugf("Logged out %s", exchange);
142 sendNoticiation(new SecurityNotification(exchange, SecurityNotification.EventType.LOGGED_OUT, account, mechanismName, true,
143 MESSAGES.userLoggedOut(account.getPrincipal().getName()), true));
144
145 this.account = null;
146 this.mechanismName = null;
147 }
148
149
153 protected static final class Node<T> {
154 final T item;
155 Node<T> next;
156
157 private Node(T item) {
158 this.item = item;
159 }
160 }
161
162 }
163