001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.authroles.authentication; 018 019import java.util.concurrent.atomic.AtomicBoolean; 020 021import org.apache.wicket.Session; 022import org.apache.wicket.request.Request; 023 024/** 025 * Basic authenticated web session. Subclasses must provide a method that authenticates the session 026 * based on a username and password, and a method implementation that gets the Roles 027 * 028 * @author Jonathan Locke 029 */ 030public abstract class AuthenticatedWebSession extends AbstractAuthenticatedWebSession 031{ 032 private static final long serialVersionUID = 1L; 033 034 /** 035 * @return Current authenticated web session 036 */ 037 public static AuthenticatedWebSession get() 038 { 039 return (AuthenticatedWebSession)Session.get(); 040 } 041 042 /** True when the user is signed in */ 043 private final AtomicBoolean signedIn = new AtomicBoolean(false); 044 045 /** 046 * Construct. 047 * 048 * @param request 049 * The current request object 050 */ 051 public AuthenticatedWebSession(Request request) 052 { 053 super(request); 054 } 055 056 /** 057 * Try to sign in the user. It'll call {@link #authenticate(String, String)} to do the real work 058 * and that is what you need to subclass to provide your own authentication mechanism. 059 * 060 * @param username 061 * @param password 062 * @return true, if logon was successful 063 */ 064 public final boolean signIn(final String username, final String password) 065 { 066 boolean authenticated = authenticate(username, password); 067 068 if (!authenticated && signedIn.get()) 069 { 070 signOut(); 071 } 072 else if (authenticated && signedIn.compareAndSet(false, true)) 073 { 074 bind(); 075 } 076 return authenticated; 077 } 078 079 /** 080 * Actual authentication check, has to be implemented by subclasses. 081 * 082 * @param username 083 * The username 084 * @param password 085 * The password 086 * @return True if the user was authenticated successfully 087 */ 088 protected abstract boolean authenticate(final String username, final String password); 089 090 /** 091 * Cookie based logins (remember me) may not rely on putting username and password into the 092 * cookie but something else that safely identifies the user. This method is meant to support 093 * these use cases. 094 * 095 * It is protected (and not public) to enforce that cookie based authentication gets implemented 096 * in a subclass (like you need to implement {@link #authenticate(String, String)} for 'normal' 097 * authentication). 098 * 099 * @see #authenticate(String, String) 100 * 101 * @param value 102 */ 103 protected final void signIn(boolean value) 104 { 105 signedIn.set(value); 106 } 107 108 /** 109 * @return true, if user is signed in 110 */ 111 @Override 112 public final boolean isSignedIn() 113 { 114 return signedIn.get(); 115 } 116 117 /** 118 * Sign the user out. 119 * <p>This method is an alias of {@link #invalidate()}</p> 120 */ 121 public void signOut() 122 { 123 invalidate(); 124 } 125 126 /** 127 * Call signOut() and remove the logon data from where ever they have been persisted (e.g. 128 * Cookies) 129 */ 130 @Override 131 public void invalidate() 132 { 133 signedIn.set(false); 134 super.invalidate(); 135 } 136}