Может ли WindowsIdentity.GetCurrent() возвращать null?

ReSharper предупреждает меня о возможном NullReferenceException в

WindowsIdentity windowsIdentity = new WindowsIdentity(WindowsIdentity.GetCurrent().Token);

Я смотрел в документе MSDN, но не видел упоминания об этом. Кроме того, это не имеет смысла, поскольку, если вы запускаете исполняемый файл, вы должны войти в систему.
Это просто шаблон поиска ReSharper?

Ответ 1

Используя ILSpy, вы можете просмотреть декомпилированную версию GetCurrent и GetCurrentInternal, которая вызывает GetCurrent. Результат:

GetCurrent:

    public static WindowsIdentity GetCurrent()
    {
        return WindowsIdentity.GetCurrentInternal(TokenAccessLevels.MaximumAllowed, false);
    }

GetCurrentInternal:

internal static WindowsIdentity GetCurrentInternal(TokenAccessLevels desiredAccess, bool threadOnly)
{
    int errorCode = 0;
    bool flag;
    SafeTokenHandle currentToken = WindowsIdentity.GetCurrentToken(desiredAccess, threadOnly, out flag, out errorCode);
    if (currentToken != null && !currentToken.IsInvalid)
    {
        WindowsIdentity windowsIdentity = new WindowsIdentity();
        windowsIdentity.m_safeTokenHandle.Dispose();
        windowsIdentity.m_safeTokenHandle = currentToken;
        return windowsIdentity;
    }
    if (threadOnly && !flag)
    {
        return null;
    }
    throw new SecurityException(Win32Native.GetMessage(errorCode));
}

Так как threadOnly всегда является ложным при вызове из GetCurrent, а currentToken должен быть действительным для другого оператора return, я не думаю, что вы рискуете получить нуль WindowsIdentity.

Ответ 2

ReSharper должен справиться с этим.

В каталоге < ReSharper install dir > \v7.1\Bin\ExternalAnnotes \.NETFramework\mscorlib - файл внешних аннотаций Nullness.Manual.xml определяет следующие аннотации:

<!-- RSRP-328266 -->
<member name="M:System.Security.Principal.WindowsIdentity.GetCurrent">
  <attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
</member>
<member name="M:System.Security.Principal.WindowsIdentity.GetCurrent(System.Boolean)">
  <attribute ctor="M:JetBrains.Annotations.ContractAnnotationAttribute.#ctor(System.String)">
    <argument>false=&gt;notnull</argument>
  </attribute>
</member>
<member name="M:System.Security.Principal.WindowsIdentity.GetCurrent(System.Security.Principal.TokenAccessLevels)">
  <attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
</member>

Однако я также получаю предупреждение о возможном исключении NullReferenceException в WindowsIdentity.GetCurrent(). По какой-то причине ReSharper не распознает свои собственные внешние атрибуты аннотации. Если это известная ошибка или если есть проблема с этой проблемой, ответьте.

Ответ 3

Это звучит как ложные сообщения от ReSharper.

Страница MSDN для GetCurrent не упоминает о возврате null при любых обстоятельствах.

Как вы указываете, должен быть текущий пользователь (того или другого), поэтому он всегда должен возвращать действительный объект - если у вас есть разрешения.

Он может поднять SecurityException, но другая ошибка и ваш код в любом случае потерпят неудачу. Если это возможность, вы можете изменить код:

WindowsIdentity currentIdentity = null;
try
{
    currentIdentity = WindowsIdentity.GetCurrent();
    // Carry on if there nothing you can do
    WindowsIdentity newIdentity = new WindowsIdentity(currentIdentity.Token);
}
catch (SecurityException ex)
{
    // Do something, logging, display error etc.
}

Ответ 4

Согласно разборке, null может быть возвращен.

Смотрите: GetCurrentInternal(TokenAccessLevels desiredAccess, bool threadOnly)

Отказ от ответственности: Я слишком ленив, чтобы проанализировать конкретное условие:)