1 package com.bradmcevoy.http;
2
3 import com.bradmcevoy.http.http11.auth.BasicAuthHandler;
4 import com.bradmcevoy.http.http11.auth.DigestAuthenticationHandler;
5 import com.bradmcevoy.http.http11.auth.NonceProvider;
6 import java.util.ArrayList;
7 import java.util.Collections;
8 import java.util.Iterator;
9 import java.util.List;
10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory;
12
13
14
15
16
17 public class AuthenticationService {
18
19 private static final Logger log = LoggerFactory.getLogger( AuthenticationService.class );
20 private List<AuthenticationHandler> authenticationHandlers;
21 private List<AuthenticationHandler> extraHandlers;
22 private List<AuthenticationHandler> allHandlers;
23 private boolean disableBasic;
24 private boolean disableDigest;
25
26
27
28
29
30
31
32 public AuthenticationService( List<AuthenticationHandler> authenticationHandlers ) {
33 this.authenticationHandlers = authenticationHandlers;
34 setAllHandlers();
35 }
36
37
38
39
40
41
42 public AuthenticationService( NonceProvider nonceProvider ) {
43 AuthenticationHandler digest = new DigestAuthenticationHandler( nonceProvider );
44 AuthenticationHandler basic = new BasicAuthHandler();
45
46 authenticationHandlers = new ArrayList<AuthenticationHandler>();
47 authenticationHandlers.add( basic );
48 authenticationHandlers.add( digest );
49 setAllHandlers();
50 }
51
52
53
54
55
56 public AuthenticationService() {
57 AuthenticationHandler digest = new DigestAuthenticationHandler();
58 AuthenticationHandler basic = new BasicAuthHandler();
59 authenticationHandlers = new ArrayList<AuthenticationHandler>();
60 authenticationHandlers.add( basic );
61 authenticationHandlers.add( digest );
62 setAllHandlers();
63 }
64
65 public void setDisableBasic( boolean b ) {
66 if( b ) {
67 Iterator<AuthenticationHandler> it = this.authenticationHandlers.iterator();
68 while( it.hasNext() ) {
69 AuthenticationHandler hnd = it.next();
70 if( hnd instanceof BasicAuthHandler ) {
71 it.remove();
72 }
73 }
74 }
75 disableBasic = b;
76 setAllHandlers();
77 }
78
79 public boolean isDisableBasic() {
80 return disableBasic;
81 }
82
83 public void setDisableDigest( boolean b ) {
84 if( b ) {
85 Iterator<AuthenticationHandler> it = this.authenticationHandlers.iterator();
86 while( it.hasNext() ) {
87 AuthenticationHandler hnd = it.next();
88 if( hnd instanceof DigestAuthenticationHandler ) {
89 it.remove();
90 }
91 }
92 }
93 disableDigest = b;
94 setAllHandlers();
95 }
96
97 public boolean isDisableDigest() {
98 return disableDigest;
99 }
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114 public AuthStatus authenticate( Resource resource, Request request ) {
115 log.trace( "authenticate" );
116 Auth auth = request.getAuthorization();
117 boolean preAuthenticated = ( auth != null && auth.getTag() != null );
118 if( preAuthenticated ) {
119 log.trace( "request is pre-authenticated" );
120 return new AuthStatus( auth, false );
121 }
122 for( AuthenticationHandler h : allHandlers ) {
123 if( h.supports( resource, request ) ) {
124 Object loginToken = h.authenticate( resource, request );
125 if( loginToken == null ) {
126 log.warn( "authentication failed by AuthenticationHandler:" + h.getClass() );
127 return new AuthStatus( auth, true );
128 } else {
129 if( log.isTraceEnabled() ) {
130 log.trace( "authentication passed by: " + h.getClass() );
131 }
132 if( auth == null ) {
133 auth = new Auth( Auth.Scheme.FORM, null, loginToken );
134 request.setAuthorization( auth );
135 }
136 auth.setTag( loginToken );
137 }
138 return new AuthStatus( auth, false );
139 }
140 }
141 return null;
142 }
143
144
145
146
147
148
149
150
151
152 public List<String> getChallenges( Resource resource, Request request ) {
153 List<String> challenges = new ArrayList<String>();
154 for( AuthenticationHandler h : allHandlers ) {
155 if( h.isCompatible( resource ) ) {
156 log.debug( "challenge for auth: " + h.getClass() );
157 String ch = h.getChallenge( resource, request );
158 challenges.add( ch );
159 } else {
160 log.debug( "not challenging for auth: " + h.getClass() + " for resource type: " + (resource == null ? "" : resource.getClass()) );
161 }
162 }
163 return challenges;
164 }
165
166 public List<AuthenticationHandler> getAuthenticationHandlers() {
167 return allHandlers;
168 }
169
170 public List<AuthenticationHandler> getExtraHandlers() {
171 return extraHandlers;
172 }
173
174 public void setExtraHandlers( List<AuthenticationHandler> extraHandlers ) {
175 this.extraHandlers = extraHandlers;
176 setAllHandlers();
177 }
178
179
180
181
182 private void setAllHandlers() {
183 List<AuthenticationHandler> handlers = new ArrayList<AuthenticationHandler>();
184 if( authenticationHandlers != null ) {
185 handlers.addAll( authenticationHandlers );
186 }
187 if( extraHandlers != null ) {
188 handlers.addAll( extraHandlers );
189 }
190 this.allHandlers = Collections.unmodifiableList( handlers );
191 }
192
193 public static class AuthStatus {
194
195 public final Auth auth;
196 public final boolean loginFailed;
197
198 public AuthStatus( Auth auth, boolean loginFailed ) {
199 this.auth = auth;
200 this.loginFailed = loginFailed;
201 }
202 }
203 }