Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
SimpleCredentialsMatcher |
|
| 2.25;2.25 |
1 | /* | |
2 | * Licensed to the Apache Software Foundation (ASF) under one | |
3 | * or more contributor license agreements. See the NOTICE file | |
4 | * distributed with this work for additional information | |
5 | * regarding copyright ownership. The ASF licenses this file | |
6 | * to you under the Apache License, Version 2.0 (the | |
7 | * "License"); you may not use this file except in compliance | |
8 | * with the License. You may obtain a copy of the License at | |
9 | * | |
10 | * http://www.apache.org/licenses/LICENSE-2.0 | |
11 | * | |
12 | * Unless required by applicable law or agreed to in writing, | |
13 | * software distributed under the License is distributed on an | |
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
15 | * KIND, either express or implied. See the License for the | |
16 | * specific language governing permissions and limitations | |
17 | * under the License. | |
18 | */ | |
19 | package org.apache.shiro.authc.credential; | |
20 | ||
21 | import org.apache.shiro.authc.AuthenticationInfo; | |
22 | import org.apache.shiro.authc.AuthenticationToken; | |
23 | import org.apache.shiro.codec.CodecSupport; | |
24 | import org.slf4j.Logger; | |
25 | import org.slf4j.LoggerFactory; | |
26 | ||
27 | import java.util.Arrays; | |
28 | ||
29 | ||
30 | /** | |
31 | * Simple CredentialsMatcher implementation. Supports direct (plain) comparison for credentials of type | |
32 | * byte[], char[], and Strings, and if the arguments do not match these types, then reverts back to simple | |
33 | * <code>Object.equals</code> comparison. | |
34 | * <p/> | |
35 | * <p>Hashing comparisons (the most common technique used in secure applications) are not supported by this class, but | |
36 | * instead by the {@link org.apache.shiro.authc.credential.HashedCredentialsMatcher HashedCredentialsMatcher}. | |
37 | * | |
38 | * @see org.apache.shiro.authc.credential.HashedCredentialsMatcher | |
39 | * @since 0.9 | |
40 | */ | |
41 | 102 | public class SimpleCredentialsMatcher extends CodecSupport implements CredentialsMatcher { |
42 | ||
43 | 1 | private static final Logger log = LoggerFactory.getLogger(SimpleCredentialsMatcher.class); |
44 | ||
45 | /** | |
46 | * Returns the {@code token}'s credentials. | |
47 | * <p/> | |
48 | * <p>This default implementation merely returns | |
49 | * {@link AuthenticationToken#getCredentials() authenticationToken.getCredentials()} and exists as a template hook | |
50 | * if subclasses wish to obtain the credentials in a different way or convert them to a different format before | |
51 | * returning. | |
52 | * | |
53 | * @param token the {@code AuthenticationToken} submitted during the authentication attempt. | |
54 | * @return the {@code token}'s associated credentials. | |
55 | */ | |
56 | protected Object getCredentials(AuthenticationToken token) { | |
57 | 12 | return token.getCredentials(); |
58 | } | |
59 | ||
60 | /** | |
61 | * Returns the {@code account}'s credentials. | |
62 | * <p/> | |
63 | * <p>This default implementation merely returns | |
64 | * {@link AuthenticationInfo#getCredentials() account.getCredentials()} and exists as a template hook if subclasses | |
65 | * wish to obtain the credentials in a different way or convert them to a different format before | |
66 | * returning. | |
67 | * | |
68 | * @param info the {@code AuthenticationInfo} stored in the data store to be compared against the submitted authentication | |
69 | * token's credentials. | |
70 | * @return the {@code account}'s associated credentials. | |
71 | */ | |
72 | protected Object getCredentials(AuthenticationInfo info) { | |
73 | 12 | return info.getCredentials(); |
74 | } | |
75 | ||
76 | /** | |
77 | * Returns {@code true} if the {@code tokenCredentials} argument is logically equal to the | |
78 | * {@code accountCredentials} argument. | |
79 | * <p/> | |
80 | * <p>If both arguments are either a byte array (byte[]), char array (char[]) or String, they will be both be | |
81 | * converted to raw byte arrays via the {@link #toBytes toBytes} method first, and then resulting byte arrays | |
82 | * are compared via {@link Arrays#equals(byte[], byte[]) Arrays.equals(byte[],byte[])}.</p> | |
83 | * <p/> | |
84 | * <p>If either argument cannot be converted to a byte array as described, a simple Object <code>equals</code> | |
85 | * comparison is made.</p> | |
86 | * <p/> | |
87 | * <p>Subclasses should override this method for more explicit equality checks. | |
88 | * | |
89 | * @param tokenCredentials the {@code AuthenticationToken}'s associated credentials. | |
90 | * @param accountCredentials the {@code AuthenticationInfo}'s stored credentials. | |
91 | * @return {@code true} if the {@code tokenCredentials} are equal to the {@code accountCredentials}. | |
92 | */ | |
93 | protected boolean equals(Object tokenCredentials, Object accountCredentials) { | |
94 | 32 | if (log.isDebugEnabled()) { |
95 | 32 | log.debug("Performing credentials equality check for tokenCredentials of type [" + |
96 | tokenCredentials.getClass().getName() + " and accountCredentials of type [" + | |
97 | accountCredentials.getClass().getName() + "]"); | |
98 | } | |
99 | 32 | if (isByteSource(tokenCredentials) && isByteSource(accountCredentials)) { |
100 | 32 | if (log.isDebugEnabled()) { |
101 | 32 | log.debug("Both credentials arguments can be easily converted to byte arrays. Performing " + |
102 | "array equals comparison"); | |
103 | } | |
104 | 32 | byte[] tokenBytes = toBytes(tokenCredentials); |
105 | 32 | byte[] accountBytes = toBytes(accountCredentials); |
106 | 32 | return Arrays.equals(tokenBytes, accountBytes); |
107 | } else { | |
108 | 0 | return accountCredentials.equals(tokenCredentials); |
109 | } | |
110 | } | |
111 | ||
112 | /** | |
113 | * This implementation acquires the {@code token}'s credentials | |
114 | * (via {@link #getCredentials(AuthenticationToken) getCredentials(token)}) | |
115 | * and then the {@code account}'s credentials | |
116 | * (via {@link #getCredentials(org.apache.shiro.authc.AuthenticationInfo) getCredentials(account)}) and then passes both of | |
117 | * them to the {@link #equals(Object,Object) equals(tokenCredentials, accountCredentials)} method for equality | |
118 | * comparison. | |
119 | * | |
120 | * @param token the {@code AuthenticationToken} submitted during the authentication attempt. | |
121 | * @param info the {@code AuthenticationInfo} stored in the system matching the token principal. | |
122 | * @return {@code true} if the provided token credentials are equal to the stored account credentials, | |
123 | * {@code false} otherwise | |
124 | */ | |
125 | public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { | |
126 | 12 | Object tokenCredentials = getCredentials(token); |
127 | 12 | Object accountCredentials = getCredentials(info); |
128 | 12 | return equals(tokenCredentials, accountCredentials); |
129 | } | |
130 | ||
131 | } |