Skip to content

Package: RememberMe$Literal

RememberMe$Literal

nameinstructionbranchcomplexitylinemethod
RememberMe.Literal(int, String, boolean, String, boolean, String, String, boolean, String)
M: 30 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 11 C: 0
0%
M: 1 C: 0
0%
cookieHttpOnly()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
cookieHttpOnlyExpression()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
cookieMaxAgeSeconds()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
cookieMaxAgeSecondsExpression()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
cookieName()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
cookieSecureOnly()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
cookieSecureOnlyExpression()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
isRememberMe()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
isRememberMeExpression()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
of(int, String, boolean, String, boolean, String, String, boolean, String)
M: 13 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
static {...}
M: 12 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * Copyright (c) 2015, 2021 Oracle and/or its affiliates and others. All rights reserved.
3: * Copyright (c) 2021 Contributors to Eclipse Foundation.
4: *
5: * This program and the accompanying materials are made available under the
6: * terms of the Eclipse Public License v. 2.0, which is available at
7: * http://www.eclipse.org/legal/epl-2.0.
8: *
9: * This Source Code may also be made available under the following Secondary
10: * Licenses when the conditions for such availability set forth in the
11: * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
12: * version 2 with the GNU Classpath Exception, which is available at
13: * https://www.gnu.org/software/classpath/license.html.
14: *
15: * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
16: */
17:
18: package jakarta.security.enterprise.authentication.mechanism.http;
19:
20: import static java.lang.annotation.ElementType.TYPE;
21: import static java.lang.annotation.RetentionPolicy.RUNTIME;
22:
23: import java.lang.annotation.Inherited;
24: import java.lang.annotation.Retention;
25: import java.lang.annotation.Target;
26:
27: import jakarta.el.ELProcessor;
28: import jakarta.enterprise.util.AnnotationLiteral;
29: import jakarta.enterprise.util.Nonbinding;
30: import jakarta.interceptor.InterceptorBinding;
31: import jakarta.security.enterprise.identitystore.IdentityStore;
32: import jakarta.security.enterprise.identitystore.RememberMeIdentityStore;
33: import jakarta.servlet.http.Cookie;
34:
35: /**
36: * The RememberMe annotation provides an application the ability to declaratively designate
37: * that an authentication mechanism effectively "remembers" the authentication and auto
38: * applies this with every request.
39: *
40: * <p>
41: * For the remember me function the credentials provided by the caller are exchanged for a (long-lived) token
42: * which is send to the user as the value of a cookie, in a similar way to how the HTTP session ID is send.
43: * It should be realized that this token effectively becomes the credential to establish the caller's
44: * identity within the application and care should be taken to handle and store the token securely. E.g.
45: * by using this feature with a secure transport (SSL/HTTPS), storing a strong hash instead of the actual
46: * token, and implementing an expiration policy.
47: *
48: * <p>
49: * The token is vended by a special purpose {@link IdentityStore}-like artifact; an implementation of the
50: * {@link RememberMeIdentityStore}.
51: *
52: * <p>
53: * This support is provided via an implementation of an interceptor spec interceptor that conducts the
54: * necessary logic.
55: *
56: * <p>
57: * Example:
58: *
59: * <pre>
60: * <code>
61: * {@literal @}RequestScoped
62: * {@literal @}RememberMe
63: * public class CustomAuthenticationMechanism implements HttpAuthenticationMechanism {
64: * // ...
65: * }
66: * </code>
67: * </pre>
68: *
69: * <p>
70: * Jakarta Expression Language expressions in attributes of type <code>String</code> are evaluated for every request requiring
71: * authentication. Both immediate and deferred syntax is supported, but effectively the semantics
72: * are always deferred.
73: *
74: * <p>
75: * <b>Note:</b> this facility <em>DOES NOT</em> constitute any kind of "session management" system, but instead
76: * represents a special purpose authentication mechanism using a long-lived token, that is vended and validated by the
77: * {@link RememberMeIdentityStore}.
78: *
79: */
80: @Inherited
81: @InterceptorBinding
82: @Retention(RUNTIME)
83: @Target(TYPE)
84: public @interface RememberMe {
85:
86: /**
87: * Max age in seconds for the remember me cookie.
88: * Defaults to one day.
89: *
90: * @see Cookie#setMaxAge(int)
91: *
92: * @return Max age in seconds
93: */
94: @Nonbinding
95: int cookieMaxAgeSeconds() default 86400; // 1 day
96:
97: /**
98: * Jakarta Expression Language expression variant of <code>cookieMaxAgeSeconds()</code>. The expression needs to
99: * evaluate to an integer outcome. All named CDI beans are available to the expression as well as default classes as
100: * specified by Jakarta Expression Language 3.0 for the {@link ELProcessor} and the implicit objects "self" which refers
101: * to the interceptor target and "httpMessageContext" which refers to the current {@link HttpMessageContext}. If both
102: * this attribute and <code>cookieMaxAgeSeconds()</code> are specified, this attribute takes precedence.
103: *
104: * @return an expression evaluating to an integer designating the max age in seconds for the remember me cookie.
105: */
106: @Nonbinding
107: String cookieMaxAgeSecondsExpression() default "";
108:
109: /**
110: * Flag to indicate that the remember me cookie should only be
111: * sent using a secure protocol (e.g. HTTPS or SSL).
112: *
113: * @see Cookie#setSecure(boolean)
114: *
115: * @return true if the cookie should be sent using a secure protocol only
116: * false for any protocol.
117: */
118: @Nonbinding
119: boolean cookieSecureOnly() default true;
120:
121: /**
122: * Jakarta Expression Language expression variant of <code>cookieSecureOnly()</code>. The expression needs to evaluate
123: * to a boolean outcome. All named CDI beans are available to the expression as well as default classes as specified by
124: * Jakarta Expression Language 3.0 for the {@link ELProcessor} and the implicit objects "self" which refers to the
125: * interceptor target and "httpMessageContext" which refers to the current {@link HttpMessageContext}. If both this
126: * attribute and <code>cookieSecureOnly()</code> are specified, this attribute takes precedence.
127: *
128: * @return an expression evaluating to an integer designating the max age in seconds for the remember me cookie.
129: */
130: @Nonbinding
131: String cookieSecureOnlyExpression() default "";
132:
133: /**
134: * Flag to indicate that the remember me cookie should not be exposed to
135: * client-side scripting code, and should only be sent with HTTP requests.
136: *
137: * @see Cookie#setHttpOnly(boolean)
138: *
139: * @return true if the cookie should be sent only with HTTP requests
140: * (and not be made available to client-side scripting code), false otherwise.
141: */
142: @Nonbinding
143: boolean cookieHttpOnly() default true;
144:
145: /**
146: * Jakarta Expression Language expression variant of <code>cookieHttpOnly()</code>. The expression needs to evaluate to
147: * a boolean outcome. All named CDI beans are available to the expression as well as default classes as specified by
148: * Jakarta Expression Language 3.0 for the {@link ELProcessor} and the implicit objects "self" which refers to the
149: * interceptor target and "httpMessageContext" which refers to the current {@link HttpMessageContext}. If both this
150: * attribute and <code>cookieHttpOnly()</code> are specified, this attribute takes precedence.
151: *
152: * @return an expression evaluating to true if the cookie should be sent only with HTTP requests , false otherwise.
153: */
154: @Nonbinding
155: String cookieHttpOnlyExpression() default "";
156:
157: /**
158: * Name of the remember me cookie.
159: *
160: * @see Cookie#getName()
161: *
162: * @return The name of the cookie
163: */
164: @Nonbinding
165: String cookieName() default "JREMEMBERMEID";
166:
167: /**
168: * Flag to determine if remember me should be used.
169: *
170: * @return Flag to determine if remember me should be used
171: */
172: @Nonbinding
173: boolean isRememberMe() default true;
174:
175: /**
176: * Jakarta Expression Language expression to determine if remember me should be used. This is evaluated for every
177: * request requiring authentication. The expression needs to evaluate to a boolean outcome. All named CDI beans are
178: * available to the expression as well as default classes as specified by Jakarta Expression Language 3.0 for the
179: * {@link ELProcessor} and the implicit objects "self" which refers to the interceptor target and "httpMessageContext"
180: * which refers to the current {@link HttpMessageContext}.
181: *
182: * @return Jakarta Expression Language expression to determine if remember me should be used
183: */
184: @Nonbinding
185: String isRememberMeExpression() default "";
186:
187: /**
188: * Supports inline instantiation of the RememberMe annotation.
189: *
190: * @since 3.0
191: */
192: public static final class Literal extends AnnotationLiteral<RememberMe> implements RememberMe {
193:
194: private static final long serialVersionUID = 1L;
195:
196: private final int cookieMaxAgeSeconds;
197: private final String cookieMaxAgeSecondsExpression;
198: private final boolean cookieSecureOnly;
199: private final String cookieSecureOnlyExpression;
200: private final boolean cookieHttpOnly;
201: private final String cookieHttpOnlyExpression;
202: private final String cookieName;
203: private final boolean isRememberMe;
204: private final String isRememberMeExpression;
205:
206: /**
207: * Default instance of the {@link RememberMe} Interceptor Binding.
208: */
209: public static final Literal INSTANCE = of(
210: 86400,
211: "",
212: true,
213: "",
214: true,
215: "",
216: "JREMEMBERMEID",
217: true,
218: ""
219: );
220:
221: /**
222: * Instance of the {@link RememberMe} Interceptor Binding.
223: *
224: * @param cookieMaxAgeSeconds Max age in seconds for the remember me cookie.
225: * @param cookieMaxAgeSecondsExpression Jakarta Expression Language expression variant of <code>cookieMaxAgeSeconds</code>
226: * @param cookieSecureOnly Flag to indicate that the remember me cookie should only be sent using a secure protocol
227: * @param cookieSecureOnlyExpression Jakarta Expression Language expression variant of <code>cookieSecureOnly</code>
228: * @param cookieHttpOnly true if the cookie should be sent only with HTTP requests
229: * @param cookieHttpOnlyExpression Jakarta Expression Language expression variant of <code>cookieHttpOnly</code>
230: * @param cookieName Name of the remember me cookie.
231: * @param isRememberMe Flag to determine if remember me should be used.
232: * @param isRememberMeExpression Jakarta Expression Language expression variant of <code>isRememberMe</code>
233: * @return instance of the {@link RememberMe} Interceptor Binding
234: */
235: public static Literal of(
236: int cookieMaxAgeSeconds,
237: String cookieMaxAgeSecondsExpression,
238: boolean cookieSecureOnly,
239: String cookieSecureOnlyExpression,
240: boolean cookieHttpOnly,
241: String cookieHttpOnlyExpression,
242: String cookieName,
243: boolean isRememberMe,
244: String isRememberMeExpression
245:
246:
247: ) {
248: return new Literal(
249: cookieMaxAgeSeconds,
250: cookieMaxAgeSecondsExpression,
251: cookieSecureOnly,
252: cookieSecureOnlyExpression,
253: cookieHttpOnly,
254: cookieHttpOnlyExpression,
255: cookieName,
256: isRememberMe,
257: isRememberMeExpression
258: );
259: }
260:
261: private Literal(
262: int cookieMaxAgeSeconds,
263: String cookieMaxAgeSecondsExpression,
264: boolean cookieSecureOnly,
265: String cookieSecureOnlyExpression,
266: boolean cookieHttpOnly,
267: String cookieHttpOnlyExpression,
268: String cookieName,
269: boolean isRememberMe,
270: String isRememberMeExpression
271: ) {
272:
273: this.cookieMaxAgeSeconds = cookieMaxAgeSeconds;
274: this.cookieMaxAgeSecondsExpression = cookieMaxAgeSecondsExpression;
275: this.cookieSecureOnly = cookieSecureOnly;
276: this.cookieSecureOnlyExpression = cookieSecureOnlyExpression;
277: this.cookieHttpOnly = cookieHttpOnly;
278: this.cookieHttpOnlyExpression = cookieHttpOnlyExpression;
279: this.cookieName = cookieName;
280: this.isRememberMe = isRememberMe;
281: this.isRememberMeExpression = isRememberMeExpression;
282: }
283:
284: @Override
285: public boolean cookieHttpOnly() {
286: return cookieHttpOnly;
287: }
288:
289: @Override
290: public String cookieHttpOnlyExpression() {
291: return cookieHttpOnlyExpression;
292: }
293:
294: @Override
295: public int cookieMaxAgeSeconds() {
296: return cookieMaxAgeSeconds;
297: }
298:
299: @Override
300: public String cookieMaxAgeSecondsExpression() {
301: return cookieMaxAgeSecondsExpression;
302: }
303:
304: @Override
305: public boolean cookieSecureOnly() {
306: return cookieSecureOnly;
307: }
308:
309: @Override
310: public String cookieSecureOnlyExpression() {
311: return cookieSecureOnlyExpression;
312: }
313:
314: @Override
315: public String cookieName() {
316: return cookieName;
317: }
318:
319: @Override
320: public boolean isRememberMe() {
321: return isRememberMe;
322: }
323:
324: @Override
325: public String isRememberMeExpression() {
326: return isRememberMeExpression;
327: }
328: }
329: }
330: